tiptap
tiptap copied to clipboard
[Bug]: Update event gets triggered unexpectedly without the document changing
Which packages did you experience the bug in?
core
What Tiptap version are you using?
2.1.16
What’s the bug you are facing?
The update event is triggered by editor.setEditable
by default, where the content had not been updated, which contradicts with the doc description (and to my opinion, the intended usage of) the update event.
At https://tiptap.dev/docs/editor/api/events#update: "The content has changed." At https://tiptap.dev/docs/editor/api/editor#set-editable: "setEditable: emitUpdate: defaults to true." First introduced by: https://github.com/ueberdosis/tiptap/issues/2850 (PR https://github.com/ueberdosis/tiptap/pull/2935)
What browser are you using?
Chrome
Code example
No response
What did you expect to happen?
The update event is not triggered if it is implemented per doc, or the doc needs to be updated to reflect it.
Anything to add? (optional)
We are using @tiptap/react
, and we wrap the editor around a component that accepts isEditable
, content
and onChange
to make it behave like a React controlled component. It behaves more or less like:
export const EditorComponent = ({ isEditable, content, onChange }) => {
// ...
useEffect(() => {
const fn = () => {
setContent(editor.getContent());
};
editor.on("update", fn);
return () => {
editor.off(fn);
};
}, [editor]);
useEffect(() => {
queueMicrotask(() => {
// This unexpectedly emits an update event.
editor.setEditable(isEditable);
});
}, [editor, isEditable]);
useEffect(() => {
queueMicrotask(() => {
// Ths does not emit an update event by default.
editor.setContent(content);
});
}, [editor, content]);
useEffect(() => {
queueMicrotask(() => {
editor.setContent(content);
});
}, [editor, content]);
}
When there are lots to render on the page, in a ~20% chance, editor.setEditable
gets called first, emitting an update event which updates the parent state with an empty document (which is the default prior to setContent
). This causes the prop content
to change, setting the content on the editor again to nothing. In the end, the content in parent state is replaced by an empty document.
This can be fixed by setting .setEditable(content, false)
, however it would still be nice to discuss how the update event should be used / documented to avoid confusion like this in the future.
Notes: I understand that using beta versions do come with disadvantages like this. setEditable(content)
's behaviour was changed from the beta (we locked to ^2.0.0-beta.109
) thanks to the issue linked above, but was not documented and cannot be found in any upgrade guides (although I might be wrong).
Would probably be nice to document this somewhere, or to put a clear warning on setEditable
as its second param has a different default value than the other commonly used command, setContent
(setEditable
defaults to true
and setContent
defaults to false
).
*The company that I work in is a Github Sponsor of this project.
Did you update your dependencies?
- [X] Yes, I’ve updated my dependencies to use the latest version of all packages.
Are you sponsoring us?
- [X] Yes, I’m a sponsor. 💖