-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error: Cannot find a descendant at path [0] in node - CRA live-reload #4081
Comments
This error occurs because To get around the issue you can use
I'm not sure if there is any downside to replacing |
I can confirm that in 0.60.4 with Why is this happening? Slate should be able to receive new editor instance without crashing, no? |
It's listed in the docs that the slate editor must be stable across renders. I believe these issues occur because information about the dom is stored in weak maps on the editor singleton. For example slate doesn't manage selection at all so information about the current selected node is stored in the editor singleton. When the editor is recreated that information is lost which leads to errors. The workaround here is one line and as far as I can tell it has no obvious downsides. |
Thanks @lukesmurray for clarification. It might be good to use ref internally in Question for mantainers: Is there any reason why this shouldn't be done? Otherwise I'll create PR. |
#3233 may be relevant. |
Still having the same even when doing |
@macroSven could you explain why your workaround in your codesandbox prevents the error from happening? |
This is code that we use: const editorRef = useRef()
if (!editorRef.current) editorRef.current = withReact(createEditor())
const editor = editorRef.current |
If you are using a version of CRA that uses Fast Refresh for hot reload and don't want to switch from official Slate examples that use This should force that particular file/component to be "remounted" and avoids this error, but it doesn't use Fast Refresh as expected then. It reloads the component, doesn't "refresh" it in place.
Could you just conditionally load the editor you want to initialize? Store some initial state in useState and then after Promise resolves, update that state and conditionally load the editor with everything you need? I'm not sure if this fits your case and if it would work properly, it's just an idea. someState && <MyRichTextEditor /> |
Thanks @marko-hologram. The conditional editor load is what I ended up doing. And I never new about the refresh comment. Will give that a try too! |
So these two workaround work: const [editor] = useState(withReact(createEditor())); and const editorRef = useRef<Editor>();
if (!editorRef.current) editorRef.current = withReact(createEditor());
const editor = editorRef.current; What's the difference between the two and are there any pros/cons one should know about? |
The workaround I use is |
const [editor] = useState(withReact(createEditor())); @aliak00 this one creates (and throws away) a new instance of the editor on every re-render, which I guess has slight performance and GC implications. The second solution with |
I think this example can be updated to use "lazy initial state" (https://reactjs.org/docs/hooks-reference.html#lazy-initial-state) that should only be computed on initial render. const [editor] = useState(() => withReact(createEditor())); In subsequent renders this won't be called and evaluated so unnecessary instances of editor won't be created. |
Why we can't just: const editorRef = useRef(withReact(createEditor()))
const editor = editorRef.current |
I think this example will just call You can probably test this by creating a custom plugin that just does a console.log. Then init your editor with that custom plugin and see if new editor instance is created on each re-render by checking if that console.log is called each time. |
What if I need to recreate editor's instance on some event? |
Not sure what would be the use case for it, but I'm guessing it could be done like this: const [editor, setEditor] = useState(() => withReact(createEditor()));
...
const handleClick = () => {
setEditor(withReact(createEditor()));
} If editor instance is kept in state, then just replace that state potentially. I haven't really worked with Slate in a long time so I forgot how most things here work 😄 |
Hey,
|
Just thought I'd let people know, if you're using your own ref, be sure to |
Do you want to request a feature or report a bug?
Bug
What's the current behavior?
Create React App live editing error on every change. Using installation instructions
To reproduce the error see this repository with a "workaround" to prevent the error.
Sandbox URL
Edit the file and you should see the error. Uncomment the lines suggested above to prevent the error.
Slate: 0.59.0
Browser: Chrome
OS: Mac
What's the expected behavior?
Live-editing should work without errors.
The text was updated successfully, but these errors were encountered: