【问题标题】:React render appending rather than replacing contentReact 渲染追加而不是替换内容
【发布时间】:2020-04-11 06:23:11
【问题描述】:

我有一个contentEditable react 组件,它会根据各种状态变化进行更新。状态项包含文本框中的段落。这些是 React 组件。下面是 3 个段落的示例状态值。

相应的文本框可能如下所示:

到 React 组件的转换发生在单击按钮时。当我用新段落更新 HTML 状态项时,我有一些奇怪的行为。它再次追加新段落而不是替换:它应该始终输出 html 状态项中包含的内容。

看起来我现在有 5 个段落组件处于状态。但我没有,我应该只看到如下四项:

我的渲染方法只是一个通过状态中的 HTML 项的映射。这有点难以解释,但希望它是有道理的。我认为这与 React 如何比较组件有关?

相关代码

// Method to update state with new HTML components
componentDidUpdate = prevProps => {
  if (prevProps.isSubmitted !== this.props.isSubmitted) {
    this.handleStateUpdate({
      html: this.createHtml()
    });
  }
};

// createHTML function is something like this, I have excluded unimportant code
createHtml = () =>
  this.props.paragraphDict.map((paragraph, key) => {
    const flaggedWords = Object.keys(paragraph);
    return (
      <Paragraph key={key}>
        {flaggedWords.map(wordId => (
          <Word key={wordId} {...props} />
        ))}
      </Paragraph>
    );
  });

// Render
render = () => {
  const { html } = this.state;

  return (
    <StyledEditor
      ref={this.el}
      contentEditable={true}
      suppressContentEditableWarning={true}
      spellCheck={false}
      onBlur={({ target }) => this.handleEditorBlur(target.innerHTML)}
    >
      {html && html.map(item => item)}
    </StyledEditor>
  );
};

【问题讨论】:

  • 完成。这还有很多其他的部分,但我认为这是相关的逻辑。
  • if (prevProps.isSubmitted !== isSubmitted) -- 你的意思是if (prevProps.isSubmitted !== this.props.isSubmitted)吗?还是isSubmitted 定义在其他地方?
  • 对不起,我愿意。我错误地删除了那部分。已更新。

标签: reactjs


【解决方案1】:

我会将此作为评论发布,但我不能这样做,而是我会在这里询问 - 您能否确认以下内容:

createHtml = () =>
  this.props.paragraphDict.map((paragraph, key) => {
    const flaggedWords = Object.keys(paragraph);
    return (
      <Paragraph key={key}>
        {flaggedWords.map(wordId => (
          <Word key={wordId} {...props} />
        ))}
      </Paragraph>
    );
  });

this.props.paragraphDict : 那是一个数组吗?名字暗示它不是,但地图表明它是。也许它应该被命名为paragraphDicts

我假设它是一个数组,在这种情况下,key 将是该数组中每个项目的索引。您将此索引作为键传递给您的 Paragraph 组件,这可能是您的问题的原因。

您可以尝试将key={key} 替换为key={paragraph.id} 之类的东西吗? (或该段落的任何其他唯一标识符)

【讨论】:

  • 感谢您的评论。你是对的,它是一个数组。我已经排除了很多,所以它不是很容易理解。关键是唯一的,这个逻辑可以正常工作。控制台日志图像是这个函数实际生成的。
  • 是的,键是唯一的,正如我所说,这里您使用索引作为键,不建议这样做 - 这里有几篇文章解释了原因: - medium.com/@robinpokorny/… - @987654322 @我不是 100% 确定这是问题所在,但很明显,您在 DOM 中看到的内容与存储在变量/状态中的内容之间存在差异 - 这里的关键是我在您的代码中唯一能发现的看起来有点“偏离”:)
【解决方案2】:

问题与键无关。为了解决这个问题,我基本上添加了一个基于当前提交状态的条件元素。然后,这将使用新内容正确地重新呈现可编辑字段,如下所示:


return isSubmitting ? (
    <StyledEditor />
    ) : (
    <StyledEditor
        ref={this.el}
        contentEditable={true}
        suppressContentEditableWarning={true}
        spellCheck={false}
        onInput={({ target }) => this.handleEditorBlur(target.innerHTML)}
    >
        {html}
    </StyledEditor>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-12
    • 2016-10-25
    • 2010-12-13
    • 1970-01-01
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    相关资源
    最近更新 更多