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>);
}
... все работает.
Нужно ли мне принудительно реагировать на повторное отображение всего компонента в этом случае, а не только на "измененные" элементы?
Ответы
Ответ 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>;