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

Text editor value disappears in 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

重现问题的步骤

->打开上面的link

->将有三个手风琴

-> 点击任何手风琴,将文本从 Expand 更改为 Shrink

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

-> 通过单击 Expand

再次打开同一个手风琴

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

我怀疑它会发生,因为每次我们 expand/shrink 时,都会调用 text_editor.js 组件并且其状态值类似于

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

这里不是EditorState.createEmpty(),还需要给其他东西吗?

要求:

如何在文本编辑器中存储已经输入的值。即使用户单击 expand/shrink,输入的文本也需要保留在编辑器中。

非常感谢任何帮助。

你是对的,输入的值丢失了,因为你正在卸载收缩的 EditorContainer 组件——当你再次展开它时,它会创建一个新的 editorState,它是空的。

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

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

  2. 我们将 EditorContainer 包裹在 div 中,当我们在 shrink/expand 之间切换时,我们将应用 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 个。