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
React js: Invariant Violation: processUpdates() when rendering a table with a different number of child rows
提问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 将无法工作。
回答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>;