【问题标题】:Why does React warn against an contentEditable component having children managed by React?为什么 React 会针对具有由 React 管理的子组件的 contentEditable 组件发出警告?
【发布时间】:2018-09-13 07:34:02
【问题描述】:

我在渲染组件时收到以下警告:

警告:组件是 contentEditable 并包含 children 由 React 管理。现在您有责任保证没有 这些节点中的一些被意外修改或复制。这是 可能不是故意的。

这是我的组件:

import React, { Component } from "react";

export default class Editable extends Component {
  render() {
    return (
      <div contentEditable={true} onBlur={this.props.handleBlur}>
        {this.props.children}
      </div>
    );
  }
}

React 想要警告我的代码的潜在问题是什么?阅读https://reactjs.org/docs/dom-elements.html的文档,我不太明白。

我想我的组件应该像托管输入字段一样工作,没有任何问题:

  1. this.props.children 为初始值
  2. onBlur 回调从event.target.innerHTML 更新道具
  3. 组件使用新的道具渲染

【问题讨论】:

  • React 警告你不要使用潜在的footgun。如果您知道如何正确处理该工具,以免它击中您的脚,那么就带着它奔跑吧。如果你设法射中自己的脚,不要感到惊讶,因为你被警告过。
  • React 不知道this.props.children 包含什么,它只知道你可以销毁那些道具。各种事情都有后果。如果有事件订阅,它们可能会成为内存泄漏,如果有绑定的属性,它们可能会成为 dangler 等等。正如 zzzBov 所说,不要自责。听起来你不会,但 React 和我们都不知道。

标签: javascript reactjs


【解决方案1】:

感谢@Chev!它修复了警告..

      <p
        className={editing ? 'editing' : ''}
        onClick={editOnClick ? this.toggleEdit : undefined}
        contentEditable={editing}
        ref={(domNode) => {
          this.domElm = domNode;
        }}
        onBlur={this.save}
        onKeyDown={this.handleKeyDown}
        {...this.props}
        suppressContentEditableWarning={true}
      >
        {this.props.value}
      </p>

【讨论】:

    【解决方案2】:

    设置contenteditable html 属性允许在浏览器中修改该元素的内容。 React 警告你,你在该元素中有由 React 管理的子元素。 React 只能从上到下工作。这意味着它在顶层管理模型并维护表示该数据的虚拟 DOM,然后基于该虚拟 DOM 呈现 DOM 树。你对 React 之外的 DOM 所做的任何更改(例如设置 contenteditable 并允许用户直接在浏览器中编辑内容)都可能会被吹走或在 React 更新这些托管元素时导致问题.

    在您的情况下,您并不关心 {this.props.children} 节点被吹走,因为您知道您正在捕捉更改并使用它做您需要做的事情。它只是警告您,当您让浏览器直接编辑内容时,最好不要期望该节点保持完整并由 React 准确更新。

    如果您知道自己在做什么(现在看起来像您这样做),那么您可以通过添加 suppressContentEditableWarning={true} 来取消该警告。

    【讨论】:

    • 嗨@Chev,谢谢它的工作!但我也很想知道缺点,抑制错误。但是,仅仅避免错误并不能保证页面上一切正常。
    • 缺点是您可能会忘记并卡住想知道为什么用户内容会被破坏。不抑制错误并不能保证一切正常。理解错误确实如此。在你的情况下,你没有做任何会遇到问题的事情,因为你只是使用 this.props.children 来设置组件的初始值。
    • @Chev 可以举一个简单的例子来说明我们什么时候会遇到问题?
    • 最近,只使用了简单的 suppressContentEditableWarning 关键字。
    猜你喜欢
    • 2018-07-09
    • 2022-10-24
    • 1970-01-01
    • 2015-01-03
    • 2015-08-16
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多