为什么 React 警告一个 contentEditable 组件不要有由 React 管理的子组件?

当呈现组件时,我会得到以下警告:

警告: 组件是 contentEditable,包含 children 现在你们有责任保证没有人 意外地修改或复制这些节点的 可能不是故意的。

这是我的组成部分:

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. 使用新的道具渲染组件
48447 次浏览

Setting the contenteditable html attribute allows the contents of that element to be modified in the browser. React is warning you that you have children within that element that are managed by React. React only works from the top down. Meaning it manages a model at the top level and maintains a virtual DOM representing that data, then renders the DOM tree based on that virtual DOM. Any changes you make to the DOM outside of React (such as setting contenteditable and allowing the content to be edited by a user directly in the browser) will be potentially blown away or cause problems for React when it goes to update those managed elements.

In your situation you don't care that the {this.props.children} node gets blown away because you know you're catching the changes and doing what you need to with it. It's just warning you that you better not expect that node to remain intact and accurately updated by React when you're letting the content be edited by the browser directly.

If you know what you're doing (and for now it looks like you do) then you can suppress that warning by adding suppressContentEditableWarning={true}.

Thanks @Chev! It fixed the warnings..

      <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>