文本编辑器值在React Js中消失

问题描述

我正在制作一个简单的手风琴,并且在每个手风琴中都有一个文本编辑器。

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 />} 用于检查单击的手风琴,然后相应地加载内容和文本编辑器。

完整的工作示例:

https://codesandbox.io/s/react-accordion-forked-dcqbo

步骤以重现该问题:

->打开上面的链接

->将会有三个手风琴

->单击任何手风琴,它将把文本从 Expand 更改为收缩

->现在在编辑器中填充一些随机文本,然后单击文本收缩

->再次点击 Expand

打开相同的手风琴

->现在已经输入的值丢失了

我怀疑是否会发生这种情况,因为每次我们进行扩展/收缩时,都会调用text_editor.js组件,并且该组件的状态值类似于

this.state = {
  editorState: EditorState.createEmpty()
};

在这里而不是EditorState.createEmpty()上,我是否还需要提供其他任何东西?

要求:

如何在文本编辑器中存储已经输入的值。即使用户单击了展开/收缩,输入的文本也必须保留在编辑器中。

非常感谢您的帮助。

解决方法

您是正确的,输入的值丢失了,因为您在缩小EditorContainer组件时正在卸载它–再次扩展它会创建一个新的editorState,它是空的。

2我可能想到的可能解决方案。

  1. editorStateonEditorStateChange移动到父组件并将其传递到EditorContainer。这样,当我们卸载EditorContainer时,我们不会丢失前一个editorState,因为它在父级上。

  2. 我们将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

Edit React-accordion (forked)