2014-11-01 2 views
20

ich die folgende Störung erhalte, wenn meine reagieren Komponente wird nach einem Klick Ereignis erneut gerendert:Reagieren js: Invariant Verletzung: processUpdates(), wenn Sie eine Tabelle mit einer unterschiedlichen Anzahl von untergeordneten Zeilen Rendering

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

Diese tritt nur auf, wenn meine Tabelle eine andere Anzahl von Zeilen als die zuvor gerenderte Version hat. Zum Beispiel:

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

Wenn ich unterschiedliche Inhalte machen, aber mit der gleichen Anzahl von Zeilen, ich habe nicht den Fehler, so dass, wenn ich die if-Anweisung aktualisieren:

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

.. . funktioniert alles.

Muss ich gezwungenermaßen reagieren, um die gesamte Komponente in diesem Fall anstatt nur der "geänderten" Elemente neu zu rendern?

+0

Dies könnte, weil Sie nicht die Elemente innerhalb des Arrays einzigartige 'Schlüssel geben werden 's. Siehe http: //facebook.github.io/react/docs/multiple-components.html, dynamische Kinder. –

+0

Sogar mit Schlüsseln hinzugefügt sehe ich das gleiche Ergebnis ... – koosa

+0

Eigentlich bedeutet das Hinzufügen von Schlüsseln bedeutet, dass auch bei Verwendung der gleichen Anzahl von Elementen bekomme ich immer noch den obigen Fehler ... – koosa

Antwort

32

Sie sollten die vollständige Fehlermeldung lesen (zumindest das ist, was ich sehe):

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.

Jeder Tabelle benötigt ein <tbody> Element. Wenn es nicht existiert, wird der Browser es hinzufügen. Reagieren funktioniert jedoch nicht, wenn das DOM von außen manipuliert wird.

Verwandte: Removing row from table results in TypeError

+8

Ah OK. Wenn React zuerst ohne tbody gerendert wird, fügt der Browser sie ein. Beim erneuten Rendern gibt es eine Diskrepanz zwischen dem, was React rendern will und dem, was im DOM ist, daher der Fehler. Danke, Tag 2 mit Reagieren hier ... – koosa

+0

Ja! Ich hoffe euch gefällt es React zu benutzen, es hat mir viel Spaß gemacht :) –

+0

Danke für den Pro-Tipp! – Micah

-1

Ich denke, Ihr Problem ist mit der Verwendung des Tags <th> in mehreren Zeilen. <th> ist für die Kopfzeile reserviert. Versuchen Sie, es mit <td> überall außer in der ersten Zeile zu ersetzen. Auch sollten Sie den Header in einem <thead>-Tag und den Rest in einem <tbody> Tag wickeln:

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

Sie können '' wo immer Sie wollen, technisch . Reagieren erzwingt keine Semantik. –

+0

Ich bekomme immer noch den gleichen Fehler mit td-Tags – koosa

+0

Ja, Entschuldigung. Ich habe die Tags vergessen, ich habe die Antwort aktualisiert – kraf

5

ich dies auf, wenn mit p Tags handelt. Ich hatte Absätze in Absätzen verschachtelt.

das Problem, das ich mit einem div Element ersetzt das Einwickeln p Element zu beheben.

Vorher:

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

Nach:

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

ah das sieht aus wie das Problem, das ich habe .. aber ohne zu sehen der umgebende Code macht dein Beispiel nicht wirklich sinnvoll. – krivar

+0

Oh, Entschuldigung! Diese Tags sollten von einer Renderfunktion in einer React-Komponente ausgegeben werden. @Krivar, ich habe meine Antwort aktualisiert, um genauer zu sein. – tukkajukka

+0

Sie können keine p-Tags innerhalb von p-Tags haben, da dies illegal ist. Browser "reparieren" es für Sie –

0

Für Menschen, die reagieren-Vorlagen verwenden:

Sie haben den <tbody>-Tag in der .jsx-Datei zu erzeugen. Wenn Sie es nur in der RT-Datei hinzufügen, erhalten Sie immer noch die Fehlermeldung.

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

In meinem Fall die Lösung ist, Räume in der Tabelle entfernen machen

<tbody> {rows} </tbody> 

zu

<tbody>{rows}</tbody> 
Verwandte Themen