javascript React js:不变违规:渲染具有不同子行数的表时的processUpdates()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26689900/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 06:19:23  来源:igfitidea点击:

React js: Invariant Violation: processUpdates() when rendering a table with a different number of child rows

javascriptreactjs

提问by koosa

I am getting the following error when my react component is re-rendered after a click event:

在单击事件后重新渲染我的 React 组件时,出现以下错误:

Uncaught Error: Invariant Violation: processUpdates(): Unable to find child 2 of element. This probably means the DOM was unexpectedly mutated ...

This only happens when my table has a different number of rows than the previously rendered version. For example:

只有当我的表的行数与之前呈现的版本不同时才会发生这种情况。例如:

/** @jsx React.DOM */

React = require('react');

var _ = require("underscore");

var testComp = React.createClass({

  getInitialState: function () {
    return { 
      collapsed: false
    };
  },

  handleCollapseClick: function(){
    this.setState({collapsed: !this.state.collapsed});
  },

  render: function() {

    var rows = [
      <tr onClick={this.handleCollapseClick}><th>Header 1</th><th>Header 2</th><th>Header 3</th></tr>
    ];

    if(!this.state.collapsed){
      rows.push(<tr><th>Row1 1</th><th>Row1 2</th><th>Row1 3</th></tr>);
    }

    rows.push(<tr><th>Footer 1</th><th>Footer 2</th><th>Footer 3</th></tr>);

    return  <div>
                <table>
                    {rows}
                </table>
            </div>
  }

});

module.exports = testComp

If I render different content, but with the same number of rows, I don't get the error, so if I update the if statement to:

如果我呈现不同的内容,但行数相同,则不会收到错误消息,因此如果我将 if 语句更新为:

if(!this.state.collapsed){
  rows.push(<tr><th>Row1 1</th><th>Row1 2</th><th>Row1 3</th></tr>);
}else{
  rows.push(<tr><th>Row2 1</th><th>Row2 2</th><th>Row2 3</th></tr>);
}

... everything works.

...一切正常。

Do I need to force react to re-render the entire component in this case, instead of just the 'changed' elements?

在这种情况下,我是否需要强制反应重新渲染整个组件,而不仅仅是“已更改”的元素?

回答by Felix Kling

You should read the full error message (at least that's what I am seeing):

您应该阅读完整的错误消息(至少这是我所看到的):

Unable to find child 2 of element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody>when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an parent.

无法找到元素的子元素 2。这可能意味着 DOM 意外地发生了变化(例如,被浏览器),通常是因为<tbody>在使用表格时忘记了 a,嵌套了<form>, <p>, or等标签,或者<a>在父级中使用了非 SVG 元素。

Every table needs a <tbody>element. If it doesn't exist, the browser will add it. However, React doesn't work if the DOM is manipulated from the outside.

每个表都需要一个<tbody>元素。如果它不存在,浏览器会添加它。但是,如果 DOM 是从外部操作的,React 将无法工作。

Related: Removing row from table results in TypeError

相关:从表中删除行导致 TypeError

回答by tukkajukka

I encountered this when dealing with ptags. I had nested paragraphs within paragraphs.

我在处理p标签时遇到了这个问题。我在段落中嵌套了段落。

To resolve the problem I replaced the wrapping pelement with a divelement.

为了解决这个问题,我用一个div元素替换了环绕的p元素。

Before:

前:

render: function render() {
    return (
        <p>
            <p>1</p>
            <p>2</p>
        </p>
    );
}

After:

后:

render: function render() {
    return (
        <div>
            <p>1</p>
            <p>2</p>
        </div>
    );
}

回答by zeillah

For people who are using react-templates:

对于使用 react-templates 的人:

You have to generate the <tbody>tag in the .jsx file. If you only add it in the .rt file you still get the error message.

您必须<tbody>在 .jsx 文件中生成标记。如果您只将它添加到 .rt 文件中,您仍然会收到错误消息。

this.tbody = <tbody>{tablerows}</tbody> // - in .jsx

回答by codegeek

In My case the fix is to remove spaces in Table render from

在我的情况下,修复是从表格渲染中删除空格

<tbody> {rows} </tbody>

to

<tbody>{rows}</tbody>

回答by kraf

I think your problem is with using the <th>tag in multiple rows. <th>is reserved for the header row. Try replacing it with <td>everywhere except in the first row. Also you should wrap the header in a <thead>tag and the rest in a <tbody>tag:

我认为您的问题是<th>在多行中使用标签。<th>为标题行保留。尝试用<td>除第一行以外的任何地方替换它。此外,您应该将标题包装在<thead>标签中,其余部分包装在<tbody>标签中:

var header = [
  <tr onClick={this.handleCollapseClick}><th>Header 1</th><th>Header 2</th><th>Header 3</th></tr>
];

var body = [];
if(!this.state.collapsed){
  body.push(<tr><td>Row1 1</td><td>Row1 2</td><td>Row1 3</td></tr>);
}

body.push(<tr><td>Footer 1</td><td>Footer 2</td><td>Footer 3</td></tr>);

 return <div>
     <table>
         <thead>{header}</thead>
         <tbody>{body}</tbody>
     </table>
 </div>;