渲染可满足的组件,而无需获得满足性的功能



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

警告:组件是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>
    );
  }
}

https://github.com/lovasoa/react-contenteditable的此组件不会生成警告。

import React from 'react';
let stripNbsp = str => str.replace(/&nbsp;|u202F|u00A0/g, ' ');
export default class ContentEditable extends React.Component {
  constructor() {
    super();
    this.emitChange = this.emitChange.bind(this);
  }
  render() {
    var { tagName, html, ...props } = this.props;
    return React.createElement(
      tagName || 'div',
      {
        ...props,
        ref: (e) => this.htmlEl = e,
        onInput: this.emitChange,
        onBlur: this.props.onBlur || this.emitChange,
        contentEditable: !this.props.disabled,
        dangerouslySetInnerHTML: {__html: html}
      },
      this.props.children);
  }
  shouldComponentUpdate(nextProps) {
    let { props, htmlEl } = this;
    // We need not rerender if the change of props simply reflects the user's edits.
    // Rerendering in this case would make the cursor/caret jump
    // Rerender if there is no element yet... (somehow?)
    if (!htmlEl) {
      return true;
    }
    // ...or if html really changed... (programmatically, not by user edit)
    if (
      stripNbsp(nextProps.html) !== stripNbsp(htmlEl.innerHTML) &&
      nextProps.html !== props.html
    ) {
      return true;
    }
    let optional = ['style', 'className', 'disabled', 'tagName'];
    // Handle additional properties
    return optional.some(name => props[name] !== nextProps[name]);
  }
  componentDidUpdate() {
    if ( this.htmlEl && this.props.html !== this.htmlEl.innerHTML ) {
      // Perhaps React (whose VDOM gets outdated because we often prevent
      // rerendering) did not update the DOM. So we update it manually now.
      this.htmlEl.innerHTML = this.props.html;
    }
  }
  emitChange(evt) {
    if (!this.htmlEl) return;
    var html = this.htmlEl.innerHTML;
    if (this.props.onChange && html !== this.lastHtml) {
      // Clone event with Object.assign to avoid 
      // "Cannot assign to read only property 'target' of object"
      var evt = Object.assign({}, evt, { 
        target: { 
          value: html 
        } 
      });
      this.props.onChange(evt);
    }
    this.lastHtml = html;
  }
}

问题:

  • 我的代码反应要警告我有什么潜在的问题?我从阅读 https://reactjs.org/docs/dom-elements.html的文档中不太了解
  • 为什么https://github.com/lovasoa/react-contenteditable的组件不生成相同的警告?

您所说的组件正在生成组件,请调用React.createElement如下因此避免了警告:

function ContentEditable(props) {
  return React.createElement('div', {contentEditable: true});
}

虽然您正在使用JSX。

function ContentEditable(props) {
  return (<div contentEditable={true}></div>);
}

您可以在这里阅读更多有关为什么反应的信息警告你。如果您想压制警告,也可以使用 suppressContentEditableWarning属性。

function ContentEditable(props) {
  return (<div contentEditable={true} suppressContentEditableWarning={true}></div>);
}

设置contenteditable时,请在浏览器中修改内容。

如果您不在后面进行反应管理而更改DOM,则反应会警告您,因为这可能会引起问题,例如更新这些元素。您正在传递直接来自React的{this.props.children},使用contenteditable将使您的内容由浏览器中的用户修改,因此可能与React不再具有控制权可能不一样。

您可以使用suppressContentEditableWarning={true}避免该警告。您要么可以使用React.createElement并通过参数{contentEditable: true}避免警告(如https://github.com/lovasoa/reaeact-contentedistication(

我不使用外部组件。我也有相同的问题,此外,如果我将div标记为内容可编辑的错误,我曾经获得无法使用dandernlyseinnerhtml的错误。我的方法与您的方法相似。因此,我没有将其标记为内容编辑。只是危险囊肿。但是在componentDidupdate中,我使用ref将DIV的套餐用作" contineDectibal = true"。我使用相同的Div抓住DIV内容进行保存。这停止了所有警告和错误。

componentDidUpdate(){
    this.htmlEl.setAttribute("contenteditable", true);
}

另外,如果您的dangesslysetinnerhtml含量包含反应组件,则可以将它们保湿以使其功能正常。但是显然您需要知道Div内部的哪个组件进行补充。

最新更新