可选:更新 Draft.js 版本
您正在使用的某些属性似乎没有记录。也许它们来自以前的版本draft-js
?但我会根据当前文档来写这个答案。
The onEditorStateChange
的支柱Editor
应该重命名为onChange https://draftjs.org/docs/api-reference-editor#onchange.
没有createFromText
on EditorState
。此替换涉及两个步骤:
-
ContentState
可以使用静态方法从文本创建ContentState.createFromText https://draftjs.org/docs/api-reference-content-state#createfromtext.
-
EditorState
可以从创建ContentState
使用静态方法EditorState.createWithContent https://draftjs.org/docs/api-reference-editor-state#createwithcontent
所以初始状态应该是:
this.state = {
editorState: EditorState.createWithContent(
ContentState.createFromText(this.props.htmlContent)
)
};
核心问题
这样,我就可以运行您的代码并重现您的问题:
我使用 props 传递来自调用者的文本,但是当文本更改(props 在 ContentEditor 中更新)时,编辑器组件中的文本不会更新。
你正在创造this.state.editorState
基于的价值this.props.htmlContent
在构造函数中。该部分代码仅在以下情况下运行一次:ControlledEditor
首先安装组件。当 props 改变时它会重新运行,所以它无法响应this.props
.
你需要添加一个componentDidUpdate https://reactjs.org/docs/react-component.html#componentdidupdate生命周期方法。
componentDidUpdate(prevProps) {
if (this.props.htmlContent !== prevProps.htmlContent) {
this.setState({
editorState: EditorState.createWithContent(
ContentState.createFromText(this.props.htmlContent)
)
});
}
}
在我看来,将其转换为函数组件并使用钩子更容易。
import { useEffect, useState } from "react";
import { Editor, EditorState, ContentState } from "draft-js";
import "draft-js/dist/Draft.css";
// helper function
const createState = (text) => {
return EditorState.createWithContent(ContentState.createFromText(text));
};
const ControlledEditor = ({ htmlContent }) => {
// define the local state, using the createState callback to create the initial value
const [editorState, setEditorState] = useState(createState(htmlContent));
// override the local state any time that the props change
useEffect(() => {
setEditorState(createState(htmlContent));
}, [htmlContent]);
return (
<Editor
editorState={editorState}
onChange={setEditorState}
/>
);
};
export default function App() {
const [text, setText] = useState("Hello World");
return (
<div>
<h2>Source Text</h2>
<textarea value={text} onChange={(e) => setText(e.target.value)} />
<h2>Editor</h2>
<ControlledEditor htmlContent={text} />
</div>
);
}