-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Description
I have added a command palette feature that opens when the user types / in the editor, but I see an error in the console when the command palette opens.
Warning: Cannot update a component (`Slate`) while rendering a different component (`ForwardRef`). To locate the bad setState() call inside `ForwardRef`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
Here is a minimal code example:
const {
openCommandPalette,
} = useCommandPalette(editor, expandEditorToMaxHeight);
// This is how openCommandPalette function looks like:
const openCommandPalette = useCallback(() => {
if (editor.selection && Range.isCollapsed(editor.selection)) {
const [start] = Range.edges(editor.selection);
setCommandPalettePosition({ anchor: start, focus: start });
setShowCommandPalette(true);
setSelectedIndex(0);
lastCommandRef.current = "";
}
}, []);
const onKeyDownHandler = (event: React.KeyboardEvent<HTMLDivElement>) => {
if (
event.key === "/" &&
!isInsideCodeBlock(editor) &&
!showCommandPalette
) {
openCommandPalette();
}
}
<Editable
readOnly={!isEditorExpanded && mode !== "edit" ? true : false}
renderElement={renderElement}
decorate={decorate}
renderLeaf={renderLeaf}
onDOMBeforeInput={handleOnDOMBeforeInput}
onKeyDown={onKeyDownHandler}
scrollSelectionIntoView={handleScrollSelectionIntoView}
className="focus-visible:outline-none flex-1 [&>*]:py-[3px] py-4 [&>*:nth-child(2)]:mt-1 break-words whitespace-pre-wrap"
tabIndex={!isEditorExpanded && mode !== "edit" ? -1 : 0}
/>Investigation:
I know that openCommandPalette() is causing this warning because wrapping it in a setTimeout fixes the problem. However, I have to use a large delay (e.g., 500ms); it does not work with 0ms:
const onKeyDownHandler = (event: React.KeyboardEvent<HTMLDivElement>) => {
if (
event.key === "/" &&
!isInsideCodeBlock(editor) &&
!showCommandPalette
) {
setTimeout(()=>{
openCommandPalette();
},500)
}
}I’ve also tried using:
- React.startTransition
- queueMicrotask
- requestAnimationFrame
All of these still produce the same warning. Only setTimeout with a larger delay avoids it.
Additional observations:
- The warning only appears when browser DevTools is open (e.g., Chrome DevTools), likely due to performance overhead.
- The error occurs only once. For example, if I clear the console and type / again, I don’t see the warning.
Question:
What is causing this warning, and how can I fix it without relying on a long setTimeout?
Environment:
"slate": "^0.114.0",
"slate-dom": "^0.114.0",
"slate-history": "^0.113.1",
"slate-react": "^0.114.2",