Skip to content

Instantly share code, notes, and snippets.

@wonderful-panda
Last active December 6, 2021 22:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wonderful-panda/e13012c4c344a93d855afedf098ee256 to your computer and use it in GitHub Desktop.
Save wonderful-panda/e13012c4c344a93d855afedf098ee256 to your computer and use it in GitHub Desktop.
difference behaviour between react and preact
/*
* With react@17.0.2, Effect-A is triggered, then Effect-B is triggered. (expected)
* With preact@10.6.2, Effect-B is triggered, then Effect-A is triggered.
*
* `useLayoutEffect` is more appropriate for Effect-A, maybe.
*
* BTW, behaviours will be same if removing React.memo call (line.39)
*/
const EditorWrapper_: React.VFC<{
value: string;
onEditorMounted?: (editor: monaco.editor.IStandaloneCodeEditor) => void;
}> = ({ value, onEditorMounted }) => {
const editorRef = useRef<HTMLDivElement>(null);
const [editor, setEditor] = useState<monaco.editor.IStandaloneCodeEditor | null>(null);
useEffect(() => {
const editor = monaco.editor.create(editorRef.current!, {});
setEditor(editor);
if (onEditorMounted) {
onEditorMounted(editor);
}
return () => {
editor.dispose();
setEditor(null);
};
}, [onEditorMounted]);
useEffect(() => {
/** Effect-A **/
if (!editor) {
return;
}
console.log("setValue");
editor?.setValue(value);
}, [editor, value]);
return <div ref={editorRef} className="absolute top-0 bottom-0 left-0 right-0" />;
};
const EditorWrapper = memo(EditorWrapper_);
const MyComponent: React.VFC<{ value: string }> = ({ value }) => {
const [editor, setEditor] = useState<monaco.editor.IStandaloneCodeEditor | null>(null);
const handleEditorMounted = useCallback((editor: IStandaloneCodeEditor) => {
setEditor(editor);
}, []);
useEffect(() => {
/** Effect-B **/
if (!editor) {
return;
}
console.log("update decoration");
const decorationIds = editor.deltaDecorations([], [
{
range: { startLineNumber: 1, endLineNumber: 2, startColumn: 1, endColumn: 1 },
options: { className: "bg-primary" }
}
]);
return () => {
// clear decoration
editor.deltaDecorations(decorationIds, []);
};
}, [editor]);
return (
<div className="relative flex-1">
<EditorWrapper value={blame.content.text} onEditorMounted={handleEditorMounted} />
</div>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment