2014-11-01 71 views
20

我收到以下错误的表时,当我反应的单击事件后组件进行重新渲染:阵营JS:不变违规:processUpdates()呈现了不同数量的子行

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

..一切正常。

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

+0

这可能是因为你没有给数组唯一'键内的元素单曲。请参阅http://facebook.github。io/react/docs/multiple-components.html,动态子项。 – 2014-11-01 13:48:47

+0

即使添加了键我也看到了相同的结果... – koosa 2014-11-01 13:55:10

+0

实际上,添加键意味着即使使用相同数量的元素时,我仍然会得到上述错误... – koosa 2014-11-01 13:59:28

回答

32

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

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.

每表格需要<tbody>元素。如果它不存在,浏览器将添加它。但是,如果从外部操纵DOM,则React不起作用。

相关:Removing row from table results in TypeError

+8

好的。当React首先呈现没有tbody的时候,浏览器会插入它。在重新渲染时,React想要呈现的内容与DOM中的内容之间存在差异,因此是错误。谢谢,第2天在这里使用React ... – koosa 2014-11-01 14:07:54

+0

是的!我希望你喜欢使用React,这对我来说已经很有趣:) – 2014-11-01 14:10:29

+0

感谢亲们的提示! – Micah 2015-02-01 19:46:32

-1

我认为你的问题是在多行中使用<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>; 
+0

您可以在任何地方使用''技术上。 React不强制执行语义。 – 2014-11-01 13:58:46

+0

我仍然使用td标签获得相同的错误 – koosa 2014-11-01 14:00:17

+0

是的,道歉。我忘记了中间的标签,我更新了答案 – kraf 2014-11-01 14:10:08

5

p标签打交道时遇到了这一点。我在段落中嵌套了段落。

为解决该问题,我用div元素替换了包装p元素。

前:

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

后:

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

啊这看起来像我遇到的问题..但没有看到周围的代码你的例子并没有多大意义。 – krivar 2015-07-27 14:00:37

+0

哦,对不起!这些标签应该由React组件中的渲染函数输出。 @krivar,我更新了我的答案,以便更准确。 – tukkajukka 2015-07-31 17:58:25

+0

您不能在p标签内使用p标签,因为它是非法的。浏览器会为您“修复”它 – 2016-03-25 17:53:00

0

对于谁是使用反应模板人:

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

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

在我的情况的解决方法是删除表空间中呈现来自

<tbody> {rows} </tbody> 

<tbody>{rows}</tbody>