How to easily set entire SlateJS editor value using React onEffect hook?
The initial editor value is set when creating the useState hook, however, I want to set a new initial value afterwards.
Currently, we can do that by deleting all elements with Transform and then inserting new elements, but is an easier way, like override all? I can't seem to find it in the SlateJS docs.
Saving to database slatejs example Don't work, but is how my setup functions
const App = () => {
const editor = useMemo(() => withReact(createEditor()), [])
// Update the initial content to be pulled from Local Storage if it exists.
const [value, setValue] = useState(
[
{
type: 'paragraph',
children: [{ text: 'A line of text in a paragraph.' }],
},
]
)
useEffect(() => {
// Get saved SlateJS text from local storage
const savedSlateTextData = getSavedSlateJSData(localStorage)
// In theory, this should set the SlateJS values to the loaded data
// In practice, I think because the editor is immutable outside transform, it don't work
setValue(savedSlateTextData)
}, [])
return (
<Slate
editor={editor}
value={value}
onChange={value => {
setValue(value)
const isAstChange = editor.operations.some(
op => 'set_selection' !== op.type
)
if (isAstChange) {
// Save the value to Local Storage.
const content = JSON.stringify(value)
localStorage.setItem('content', content)
}
}}
>
<Editable />
</Slate>
)
}
Years later I'm looking at this again and the initial value is an initial value that cannot be changed dynamically by simply setting it to something else. You'd need to use onChange if you wanted to set a new value after the API response comes back.
Otherwise, re-initialise the entire slate editor. I found the easiest way is with a key. Basically, when the key value changes, then slate will reinialise itself. So then update the key when the backend data arrives.
import { v7 as uuidv7 } from 'uuid'
const backendData = useAppSelector(selectBackendData)
const [uniqueKey, setUniqueKey] = useState(uuidv7())
const populatedInitialValue: Descendant[] = useMemo(() => {
if (backendData.length <= 0) return [
{
type: ElementTypes.PARAGRAPH,
children: [{ text: 'Default Initial Paragraph Content' }],
},
]
setUniqueKey(uuidv7())
return backendData
}, [backendData])
return (
<Slate
key={uniqueKey}
editor={editor}
initialValue={populatedInitialValue}
>
</Slate>
)
"slate": "^0.112.0",