问题描述
我正在制作一个简单的手风琴,并且在每个手风琴中都有一个文本编辑器。
Accordion.js
<div className="wrapper">
{accordionData.map((item,index) => (
<Accordion>
<heading>
<div
style={{ padding: "10px",cursor: "pointer" }}
className="heading"
onClick={() => toggleHandler(index)}
>
{toggleValue !== index ? `Expand` : `Shrink`}
</div>
</heading>
<Text> {toggleValue === index && item.content && <EditorContainer />} </Text>
</Accordion>
))}
</div>
在这里,手风琴是作为组成部分组成的。该行{toggleValue === index && item.content && <EditorContainer />}
用于检查单击的手风琴,然后相应地加载内容和文本编辑器。
完整的工作示例:
步骤以重现该问题:
->打开上面的链接
->将会有三个手风琴
->单击任何手风琴,它将把文本从 Expand 更改为收缩
->现在在编辑器中填充一些随机文本,然后单击文本收缩
->再次点击 Expand
打开相同的手风琴->现在已经输入的值丢失了
我怀疑是否会发生这种情况,因为每次我们进行扩展/收缩时,都会调用text_editor.js组件,并且该组件的状态值类似于
this.state = {
editorState: EditorState.createEmpty()
};
在这里而不是EditorState.createEmpty()上,我是否还需要提供其他任何东西?
要求:
如何在文本编辑器中存储已经输入的值。即使用户单击了展开/收缩,输入的文本也必须保留在编辑器中。
非常感谢您的帮助。
解决方法
您是正确的,输入的值丢失了,因为您在缩小EditorContainer
组件时正在卸载它–再次扩展它会创建一个新的editorState
,它是空的。
2我可能想到的可能解决方案。
-
将
editorState
和onEditorStateChange
移动到父组件并将其传递到EditorContainer
。这样,当我们卸载EditorContainer
时,我们不会丢失前一个editorState
,因为它在父级上。 -
我们将
EditorContainer
包装在div
内,并在收缩/扩展之间切换时应用display
样式。这样,我们只隐藏EditorContainer
而不卸载,因此它的states
将保留。
我选择实施第二个解决方案,因为我们只需要对Accordion.js
文件进行更改。无论哪种方式,我都会创建一个新组件来处理当前项目。我称之为NormalAccordionItem
。
const NormalAccordionItem = ({ data }) => {
const [show,setShow] = useState(false);
function toggle() {
setShow((prev) => !prev);
}
return (
<Accordion>
<Heading>
<div
style={{ padding: "10px",cursor: "pointer" }}
className="heading"
onClick={toggle}
>
{show ? "Shrink" : "Expand"}
</div>
</Heading>
<Text>
<div style={{ display: show ? "block" : "none" }}> // notice this
<EditorContainer />
</div>
</Text>
</Accordion>
);
};
然后在我们的NormalAccordion
上使用NormalAccordionItem
。
const NormalAccordion = () => {
return (
<div className="wrapper">
{accordionData.map((data) => (
<NormalAccordionItem data={data} key={data.id} />
))}
</div>
);
};
就这样,请查看下面的演示。
编辑:已更新演示,一次可以展开NormalAccordionItem
。