Vee*_*era 3 javascript reactjs draftjs react-hooks
我有一个简单的用例:有一个 DraftEditor 组件,该组件将value其作为道具并基于value(空或有内容)创建编辑器状态。可能value会被父级更改,当它更改时,我希望草稿编辑器也更新它的内容。这是我的DraftEditor组件。
import React, { useState } from "react";
import { Editor, EditorState, convertFromRaw } from "draft-js";
export default ({ value }) => {
const initialState = value
? EditorState.createWithContent(convertFromRaw(JSON.parse(value)))
: EditorState.createEmpty();
const [editorState, setEditorState] = useState(initialState);
return <Editor editorState={editorState} onChange={setEditorState} />;
};
Run Code Online (Sandbox Code Playgroud)
问题:当value被父组件更新时,内容Editor没有得到更新。相反,它只显示初始化的内容。我发现的解决方法是setEditorState在value更改时手动调用,但我觉得这一步是不必要的,因为当组件重新渲染时,我希望编辑器也重新计算它的内部状态?可能是我在这里遗漏了什么?
知道为什么Editor不更新它的内部状态吗?
这是一个代码沙箱:https : //codesandbox.io/s/xenodochial-sanderson-i95vd? fontsize =14& hidenavigation =1& theme =dark
基本问题是
const [editorState, setEditorState] = useState(initialState);
Run Code Online (Sandbox Code Playgroud)
initialState无论initialState更改多少次,都只使用它的参数一次(在初始运行时)。
当使用useState()并且有一个 prop(或其他)依赖项时,将它与 a 配对useEffect()以使事物具有反应性。
这可能看起来有点倒退,但很多(大部分)钩子都是关于在重新运行 Function 组件时保持相同的东西。所以useState()只能editorState通过setEditorState, 在初始调用后更新。
import React, { useState, useEffect } from "react";
import { Editor, EditorState, convertFromRaw } from "draft-js";
export default ({ value }) => {
const [editorState, setEditorState] = useState();
useEffect(() => {
const state = value
? EditorState.createWithContent(convertFromRaw(JSON.parse(value)))
: EditorState.createEmpty();
setEditorState(state);
}, [value]); // add 'value' to the dependency list to recalculate state when value changes.
return <Editor editorState={editorState} onChange={setEditorState} />;
};
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,editorState 在初始组件调用时将为 null。如果这是Editor组件的问题,您可以在函数中外部化状态计算,useState()并在useEffect().
import React, { useState, useEffect } from "react";
import { Editor, EditorState, convertFromRaw } from "draft-js";
export default ({ value }) => {
const [editorState, setEditorState] = useState(calcState(value));
useEffect(() => {
setEditorState(calcState(value));
}, [value]); // add 'value' to the dependency list to recalculate state when value changes.
return <Editor editorState={editorState} onChange={setEditorState} />;
};
const calcState = (value) => {
return value
? EditorState.createWithContent(convertFromRaw(JSON.parse(value)))
: EditorState.createEmpty();
}
Run Code Online (Sandbox Code Playgroud)
由于这两个钩子经常一起使用,我倾向于将它们配对在自定义钩子中以封装细节。
不同之处在于自定义钩子在每次 Component 运行时都会运行,但editorState仍然只在 value 更改时更新。
定制挂钩
import React, { useState, useEffect } from "react";
import { EditorState, convertFromRaw } from "draft-js";
export const useConvertEditorState = (value) => {
const [editorState, setEditorState] = useState(calcState(value));
useEffect(() => {
setEditorState(calcState(value));
}, [value]);
return [editorState, setEditorState];
}
const calcState = (value) => {
return value
? EditorState.createWithContent(convertFromRaw(JSON.parse(value)))
: EditorState.createEmpty();
}
Run Code Online (Sandbox Code Playgroud)
成分
import React, { useState, useEffect } from "react";
import { Editor } from "draft-js";
import { useConvertEditorState } from './useConvertEditorState'
export default ({ value }) => {
const [editorState, setEditorState] = useConvertEditorState(value);
return <Editor editorState={editorState} onChange={setEditorState} />;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1943 次 |
| 最近记录: |