当父组件更改其值时,Draft JS 编辑器不会更新其内容?
Draft JS editor does not update it's content when its value changed by parent component?
我有一个简单的用例:有一个 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} />;
};
问题:当父组件更新value
时,Editor
的内容没有更新。相反,它只显示初始化时使用的内容。我找到的解决方法是在 value
更改时手动调用 setEditorState
,但我觉得这一步是不必要的,因为当组件重新呈现时我希望编辑器也重新计算它的内部状态?可能是我遗漏了什么?
知道为什么 Editor
没有更新它的内部状态吗?
这是一个代码沙箱:https://codesandbox.io/s/xenodochial-sanderson-i95vd?fontsize=14&hidenavigation=1&theme=dark
基本问题是
const [editorState, setEditorState] = useState(initialState);
只使用它的参数 initialState
一次(在初始 运行-through),无论 initialState
更改多少次。
当使用 useState()
并且存在 prop(或其他)依赖项时,将其与 useEffect()
配对以使其具有反应性。
这可能看起来有点倒退,但是很多(大部分)钩子都是关于在函数组件重新运行时保持不变的。因此 useState()
仅在初始调用后通过 setEditorState
更新 editorState
。
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} />;
};
在上面的代码中,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();
}
由于这两个挂钩经常一起使用,我倾向于将它们配对在一个自定义挂钩中以封装细节。
不同之处在于,自定义挂钩 运行s 每次组件 运行s,但 editorState
仍然仅在值更改时更新。
自定义挂钩
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();
}
组件
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} />;
};
我有一个简单的用例:有一个 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} />;
};
问题:当父组件更新value
时,Editor
的内容没有更新。相反,它只显示初始化时使用的内容。我找到的解决方法是在 value
更改时手动调用 setEditorState
,但我觉得这一步是不必要的,因为当组件重新呈现时我希望编辑器也重新计算它的内部状态?可能是我遗漏了什么?
知道为什么 Editor
没有更新它的内部状态吗?
这是一个代码沙箱:https://codesandbox.io/s/xenodochial-sanderson-i95vd?fontsize=14&hidenavigation=1&theme=dark
基本问题是
const [editorState, setEditorState] = useState(initialState);
只使用它的参数 initialState
一次(在初始 运行-through),无论 initialState
更改多少次。
当使用 useState()
并且存在 prop(或其他)依赖项时,将其与 useEffect()
配对以使其具有反应性。
这可能看起来有点倒退,但是很多(大部分)钩子都是关于在函数组件重新运行时保持不变的。因此 useState()
仅在初始调用后通过 setEditorState
更新 editorState
。
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} />;
};
在上面的代码中,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();
}
由于这两个挂钩经常一起使用,我倾向于将它们配对在一个自定义挂钩中以封装细节。
不同之处在于,自定义挂钩 运行s 每次组件 运行s,但 editorState
仍然仅在值更改时更新。
自定义挂钩
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();
}
组件
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} />;
};