I’m using Lexical to add a rich text editor to a React project. To test how this works, I’ve added two Lexical editors to a single page. One editor is “editable”, the other is in read only mode. I have a save button that should allow the text from one editor to be displayed in the other.
I would like to be able to display text in a Lexical editor that has previously been saved as a JSON string.
Here is my full code:
import {AutoFocusPlugin} from '@lexical/react/LexicalAutoFocusPlugin';
import {LexicalComposer} from '@lexical/react/LexicalComposer';
import {ContentEditable} from '@lexical/react/LexicalContentEditable';
import {LexicalErrorBoundary} from '@lexical/react/LexicalErrorBoundary';
import {HistoryPlugin} from '@lexical/react/LexicalHistoryPlugin';
import {RichTextPlugin} from '@lexical/react/LexicalRichTextPlugin';
import {OnChangePlugin} from '@lexical/react/LexicalOnChangePlugin';
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
import ExampleTheme from './ExampleTheme.ts';
import ToolbarPlugin from './ToolbarPlugin.tsx';
import React, { useState } from 'react';
// import TreeViewPlugin from './TreeViewPlugin.tsx';
function Placeholder() {
return <div className="editor-placeholder">Enter some rich text...</div>;
}
const editorConfig = {
namespace: 'Editor',
nodes: [],
// Handling of errors during update
onError(error: Error) {
throw error;
},
// The editor theme
theme: ExampleTheme,
};
const readerConfig = {
namespace: 'Reader',
nodes: [],
// Handling of errors during update
onError(error: Error) {
throw error;
},
// The editor theme
theme: ExampleTheme,
editable: false,
};
export default function TextEditor() {
const [editorState, setEditorState] = useState<string>();
const [readerState, setReaderState] = useState<string>();
function UpdatePlugin() {
const [editor] = useLexicalComposerContext();
editor.setEditorState(editor.parseEditorState(readerState));
return null;
}
function onChange(editorState) {
const editorStateJSON = editorState.toJSON();
setEditorState(JSON.stringify(editorStateJSON));
}
function toggleEditable(){
console.log("toggling editability")
}
function saveButton() {
console.log(editorState);
setReaderState(editorState);
}
return (
<div>
<LexicalComposer initialConfig={editorConfig}>
<div className="editor-container">
<ToolbarPlugin />
<div className="editor-inner">
<RichTextPlugin
contentEditable={<ContentEditable className="editor-input" />}
placeholder={<Placeholder />}
ErrorBoundary={LexicalErrorBoundary}
/>
<HistoryPlugin />
<AutoFocusPlugin />
<OnChangePlugin onChange={onChange} />
{/* <TreeViewPlugin /> */}
</div>
<button
className='text-edit-button'
title='Update overview description'
onClick={() => saveButton()}
>Print to reader</button>
<button
className='text-edit-button'
title='Update overview description'
onClick={() => toggleEditable()}
>Toggle</button>
</div>
</LexicalComposer>
<LexicalComposer initialConfig={readerConfig}>
<div className="editor-container">
<div className="editor-inner">
<RichTextPlugin
contentEditable={<ContentEditable className="editor-input" />}
placeholder={<Placeholder />}
ErrorBoundary={LexicalErrorBoundary}
/>
<UpdatePlugin />
</div>
<button
className='text-edit-button'
title='Update overview description'
onClick={() => toggleEditable()}
>Toggle</button>
</div>
</LexicalComposer>
</div>
);
}
This code produces the following error message:
Argument of type ‘string | undefined’ is not assignable to parameter of type ‘string | SerializedEditorState<SerializedLexicalNode>’.
Type ‘undefined’ is not assignable to type ‘string | SerializedEditorState<SerializedLexicalNode>’.
However, when the following lines are commented out, the page loads correctly:
function UpdatePlugin() {
const [editor] = useLexicalComposerContext();
editor.setEditorState(editor.parseEditorState(readerState));
return null;
}
And:
<UpdatePlugin />
Once the page is loaded, I can uncomment those lines, save the file, and the page works as intended. However, when I refresh the page, I receive Uncaught runtime errors:
Cannot read properties of undefined (reading ‘root’)
TypeError: Cannot read properties of undefined (reading ‘root’)
at parseEditorState