Skip to content

Commit 21a19a1

Browse files
committed
Prevent the Monaco editor from being recreated on every keystroke.
Split the actions dependency out into a separate effect. Use a ref for runCode so that we can memoize amaranthSourceEditorActions and not re-run the actions effect on every render either.
1 parent 698d71f commit 21a19a1

File tree

2 files changed

+24
-11
lines changed

2 files changed

+24
-11
lines changed

src/app.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,20 @@ function AppContent() {
157157
}
158158
}, [amaranthSource, amaranthVersion]);
159159

160+
const runCodeRef = useRef(runCode);
161+
runCodeRef.current = runCode;
162+
163+
const amaranthSourceEditorActions = React.useMemo(() => [
164+
{
165+
id: 'amaranth-playground.run',
166+
label: 'Run Code',
167+
keybindings: [
168+
monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter,
169+
],
170+
run: runCodeRef.current,
171+
}
172+
], [runCodeRef]);
173+
160174
function tabAndPanel({ key, title, titleStyle = {}, content }) {
161175
return [
162176
<Tab key={`${key}-tab`} value={key} style={titleStyle}>{title}</Tab>,
@@ -307,16 +321,7 @@ function AppContent() {
307321
title: 'Amaranth Source',
308322
content: <Editor
309323
state={amaranthSourceEditorState.current}
310-
actions={[
311-
{
312-
id: 'amaranth-playground.run',
313-
label: 'Run Code',
314-
keybindings: [
315-
monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter,
316-
],
317-
run: runCode,
318-
}
319-
]}
324+
actions={amaranthSourceEditorActions}
320325
padding={{ top: 10, bottom: 10 }}
321326
focus
322327
/>

src/monaco.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ export function Editor({ state, actions = [], padding, focus = false }: EditorPr
5252
readOnly: state.readOnly,
5353
padding,
5454
});
55-
actions.forEach(action => editorRef.current?.addAction(action));
5655
const resizeObserver = new ResizeObserver(events => editorRef.current?.layout());
5756
resizeObserver.observe(containerRef.current!);
5857
editorRef.current.restoreViewState(state.viewState);
@@ -63,6 +62,15 @@ export function Editor({ state, actions = [], padding, focus = false }: EditorPr
6362
resizeObserver.disconnect();
6463
editorRef.current?.dispose();
6564
};
65+
}, []);
66+
67+
useEffect(() => {
68+
if (!editorRef.current)
69+
return;
70+
const disposables = actions.map(action => editorRef.current!.addAction(action));
71+
return () => {
72+
disposables.forEach(disposable => disposable.dispose());
73+
};
6674
}, [actions]);
6775

6876
return <div style={{ height: '100%' }} ref={containerRef}/>;

0 commit comments

Comments
 (0)