Controlled Editor Value
How to control the editor value.
Implementing a fully controlled editor value in Plate (and Slate) is complex due to several factors:
-
The editor state includes more than just the content (
editor.children
). It also includeseditor.selection
andeditor.history
. -
Directly replacing
editor.children
can break the selection and history, leading to unexpected behavior or crashes. -
All changes to the editor's value should ideally happen through Transforms to maintain consistency with selection and history.
Given these challenges, it's generally recommended to use Plate as an uncontrolled input. However, if you need to make external changes to the editor's content, you can use editor.tf.setValue(value)
function.
Using editor.tf.setValue
will re-render all nodes on each call, so it
should be used carefully and sparingly. It may impact performance if used
frequently or with large documents.
Alternatively, you can use editor.tf.reset()
to reset the editor state, which will reset the selection and history.
function App() {
const editor = usePlateEditor({
value: 'Initial Value',
// Disable the editor if initial value is not yet ready
// enabled: !!value,
});
return (
<div>
<Plate editor={editor}>
<PlateContent />
</Plate>
<button
onClick={() => {
// Replace with HTML string
editor.tf.setValue('Replaced Value');
// Replace with JSON value
editor.tf.setValue([
{
type: 'p',
children: [{ text: 'Replaced Value' }],
},
]);
// Replace with empty value
editor.tf.setValue();
}}
>
Replace Value
</button>
<button
onClick={() => {
editor.tf.reset();
}}
>
Reset Editor
</button>
</div>
);
}
'use client';
import React from 'react';
import {
Plate,
focusEditor,
focusEditorEdge,
usePlateEditor,
} from '@udecode/plate-common/react';
import { Button } from '@/components/plate-ui/button';
import { Editor, EditorContainer } from '@/components/plate-ui/editor';
export default function ControlledEditorDemo() {
const editor = usePlateEditor({
value: [
{
children: [{ text: 'Initial Value' }],
type: 'p',
},
],
});
return (
<div>
<Plate editor={editor}>
<EditorContainer>
<Editor />
</EditorContainer>
</Plate>
<div className="mt-4 flex flex-col gap-2">
<Button
onClick={() => {
// Replace with HTML string
editor.tf.setValue([
{
children: [{ text: 'Replaced Value' }],
type: 'p',
},
]);
focusEditorEdge(editor, { edge: 'end' });
}}
>
Replace Value
</Button>
<Button
onClick={() => {
editor.tf.reset();
focusEditor(editor);
}}
>
Reset Editor
</Button>
</div>
</div>
);
}