Skip to content

Commit 3393404

Browse files
author
Anders Hafreager
committed
fix: replace direct state mutation in editor with proper store action
Fixes #300 The onEditorChange callback in Edit.tsx was directly mutating file.content on the simulation object, bypassing easy-peasy's immutability contract. - Added updateFileContent action to SimulationModel that immutably updates the matching file in simulation.files - Updated Edit.tsx to dispatch this action via useStoreActions - Editor now reads content from simulation.files (source of truth) instead of the stale selectedFile reference
1 parent 6711045 commit 3393404

2 files changed

Lines changed: 27 additions & 10 deletions

File tree

src/containers/Edit.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useCallback } from "react";
2-
import { useStoreState } from "../hooks";
2+
import { useStoreActions, useStoreState } from "../hooks";
33
import Editor, { loader } from "@monaco-editor/react";
44
import type * as Monaco from "monaco-editor";
55
import { registerLammpsLanguage } from "../utils/lammpsLanguage";
@@ -12,6 +12,12 @@ loader.init().then((monaco) => {
1212
const Edit = () => {
1313
const selectedFile = useStoreState((state) => state.app.selectedFile);
1414
const simulation = useStoreState((state) => state.simulation.simulation);
15+
const updateFileContent = useStoreActions(
16+
(actions) => actions.simulation.updateFileContent,
17+
);
18+
const currentFile =
19+
simulation?.files.find((file) => file.fileName === selectedFile?.fileName) ??
20+
selectedFile;
1521
const options = {
1622
selectOnLineNumbers: true,
1723
};
@@ -25,15 +31,10 @@ const Edit = () => {
2531

2632
const onEditorChange = useCallback(
2733
(newValue: string | undefined) => {
28-
if (!newValue) return;
29-
const file = simulation?.files.find(
30-
(file) => file.fileName === selectedFile?.fileName,
31-
);
32-
if (file) {
33-
file.content = newValue;
34-
}
34+
if (newValue === undefined || !selectedFile?.fileName) return;
35+
updateFileContent({ fileName: selectedFile.fileName, content: newValue });
3536
},
36-
[selectedFile?.fileName, simulation?.files],
37+
[selectedFile?.fileName, updateFileContent],
3738
);
3839

3940
if (!selectedFile) {
@@ -45,7 +46,7 @@ const Edit = () => {
4546
height="100vh"
4647
language="lammps"
4748
theme="vs-dark"
48-
value={selectedFile.content}
49+
value={currentFile?.content}
4950
options={options}
5051
onChange={onEditorChange}
5152
onMount={handleEditorDidMount}

src/store/simulation.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ export interface SimulationModel {
5454
setCameraPosition: Action<SimulationModel, THREE.Vector3 | undefined>;
5555
setCameraTarget: Action<SimulationModel, THREE.Vector3 | undefined>;
5656
setSimulation: Action<SimulationModel, Simulation>;
57+
updateFileContent: Action<
58+
SimulationModel,
59+
{ fileName: string; content: string }
60+
>;
5761
setRunning: Action<SimulationModel, boolean>;
5862
setFiles: Action<SimulationModel, string[]>;
5963
setLammps: Action<SimulationModel, LammpsWeb>;
@@ -96,6 +100,18 @@ export const simulationModel: SimulationModel = {
96100
setSimulation: action((state, simulation: Simulation) => {
97101
state.simulation = simulation;
98102
}),
103+
updateFileContent: action((state, { fileName, content }) => {
104+
if (!state.simulation) {
105+
return;
106+
}
107+
108+
state.simulation = {
109+
...state.simulation,
110+
files: state.simulation.files.map((file) =>
111+
file.fileName === fileName ? { ...file, content } : file,
112+
),
113+
};
114+
}),
99115
setRunning: action((state, running: boolean) => {
100116
state.running = running;
101117
}),

0 commit comments

Comments
 (0)