Подтвердить что ты не робот

React js: Invariant Violation: processUpdates() при рендеринге таблицы с другим количеством дочерних строк

Я получаю следующую ошибку, когда мой компонент реагирования повторно отображается после события click:

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

Это происходит только тогда, когда моя таблица имеет другое количество строк, чем предыдущая версия. Например:

/** @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:

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>);
}

... все работает.

Нужно ли мне принудительно реагировать на повторное отображение всего компонента в этом случае, а не только на "измененные" элементы?

4b9b3361

Ответ 1

Вы должны прочитать полное сообщение об ошибке (по крайней мере, то, что я вижу):

Невозможно найти дочерний элемент 2 элемента. Вероятно, это означает, что DOM неожиданно мутировался (например, браузером), обычно из-за забывания <tbody> при использовании таблиц, вложенных тегов типа <form>, <p> или <a>, или использование элементов, отличных от SVG, в родительском.

Каждой таблице нужен элемент <tbody>. Если он не существует, браузер добавит его. Однако React не работает, если DOM управляется снаружи.

Связано: Удаление строки из таблицы приводит к использованию TypeError

Ответ 2

Я столкнулся с этим при работе с тэгами. У меня были вложенные абзацы в параграфах.

Чтобы решить проблему, я заменил элемент wrapping p на элемент div.

До:

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

После:

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

Ответ 3

Для людей, которые используют шаблоны реакции:

Вам нужно сгенерировать тэг <tbody> в файле .jsx. Если вы добавите его только в файл .rt, вы получите сообщение об ошибке.

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

Ответ 4

В моем случае исправление заключается в удалении пробелов в рендеринге таблицы из

<tbody> {rows} </tbody>

к

<tbody>{rows}</tbody>

Ответ 5

Я думаю, что ваша проблема заключается в использовании тега <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>;