2017-08-31 1 views
0

Wie funktioniert der React-Schlüssel?

import React from 'react' 
 
import ReactDOM from 'react-dom' 
 

 
class App extends React.Component{ 
 
\t constructor(props) { 
 
\t \t  super(props) 
 
\t \t  this.state = { 
 
\t \t \t  list: [{id: 1,val: 'aa'}, {id: 2, val: 'bb'}, {id: 3, val: 'cc'}] 
 
\t \t  } 
 
\t } 
 

 
\t click() { 
 
\t \t  this.state.list.reverse() 
 
\t \t  this.setState({}) 
 
\t } 
 

 
\t render() { 
 
\t \t  return (
 
      <ul> 
 
       <div onClick={this.click.bind(this)}>reverse</div> 
 
       { 
 
       \t this.state.list.map(function(item, index) { 
 
       \t \t return (
 
          <Li key={item.id} val={item.val}></Li> 
 
       \t \t) 
 
       \t }.bind(this)) 
 
       } 
 
      </ul> 
 
\t \t ) 
 
\t } 
 
} 
 

 
class Li extends React.Component{ 
 
\t constructor(props) { 
 
\t \t  super(props) 
 
\t } 
 
\t componentDidMount() { 
 
\t \t  console.log('===did===') 
 
\t } 
 
\t componentWillUpdate(nextProps, nextState) { 
 
\t \t  console.log('===mount====') 
 
\t } 
 
\t render() { 
 
\t \t  return (
 
      <li> 
 
       {this.props.val} 
 
       <input type="text"></input> 
 
      </li> 
 
\t \t ) 
 
\t } 
 
} 
 

 
ReactDOM.render(<App/>, document.getElementById('app'))

wenn ich Schlüssel als item.id gesetzt, und ich stellte drei Eingangs-Tags a, b, c;

wenn ich umkehren klicken, wird die Komponente Li montieren wird, wird Eingang umkehren

wenn ich Schlüssel als index ändern, wenn ich umkehren klicken, um die Komponente Li aktualisieren und die Input-Tag wird sich nicht ändern,

Ich möchte wissen, wie es passiert? Hat jemand herausgefunden, wie der Schlüssel funktioniert?

Antwort

2

Wie @DuncanThacker erklärt die key wird verwendet, um eindeutige Elemente zu identifizieren, so dass zwischen 2 Render-Passagen React weiß, ob ein Element eine neue Sache oder eine aktualisierte Sache ist. Denken Sie daran, dass React-Diffs jedes Rendering durchführen, um festzustellen, was sich im DOM tatsächlich geändert hat.

nun das Verhalten erklären Sie sehen:

wenn ich Schlüssel als item.id gesetzt, und ich stellte drei Eingangs-Tags a, b, c;

wenn ich umkehren klicken, wird montieren die Komponente Li, wird Eingang

umkehren Wenn Sie id als key verwenden können Sie das Array neu zu ordnen, sondern reagieren nur erstellen und den Knoten der erste Halterung Zeit. Sie geben ===mount=== innerhalb componentWillUpdate aus, weshalb Sie diese irreführende Ausgabe sehen, aber React aktualisiert nur die Knoten (verschiebt sie nach Bedarf). Der Zustand der inneren input folgt auch jeder <Li> Komponente an ihre neue Position, da React korrekt versteht, dass die verschoben, nicht einfach mit anderem Inhalt neu gezeichnet.

wenn ich Schlüssel als index ändern, wenn ich umkehren klicken, wird die Komponente Li aktualisieren und die Input-Tag nicht

ändern Wenn Sie index als key effektiv Reagieren jeder sieht, wie Render Pass Rendering das Array in der gleichen Reihenfolge aber mit unterschiedlichem Inhalt, da jedes Element key ist das gleiche index egal, in welcher Reihenfolge der Array-Inhalt ist in.Dies ist auch der Grund, warum das innere input an der gleichen Stelle bleibt, obwohl das val Etikett an einer anderen Position gerendert wird. Und genau deshalb sollten Sie nicht index als key verwenden.

Man könnte es so verdeutlichen:

|-----------------------|---------------------|--------------------------| 
|  Before   |  After  |   Change   | 
|-----------------------|---------------------|--------------------------| 

Array:

|-----------------------|---------------------|--------------------------| 
| { id: 1, val: "A" } | { id: 3, val: "C" } | Moved from last to first | 
| { id: 2, val: "B" } | { id: 2, val: "B" } | None      | 
| { id: 3, val: "C" } | { id: 1, val: "A" } | Moved from first to last | 
|-----------------------|---------------------|--------------------------| 

Render key von index:

|-----------------------|---------------------|--------------------------| 
| <Li key=0 val="A"> | <Li key=0 val="C"> | Val changed "A" to "C" | 
| <Li key=1 val="B"> | <Li key=1 val="B"> | None      | 
| <Li key=2 val="C"> | <Li key=2 val="A"> | Val changed "C" to "A" | 
|-----------------------|---------------------|--------------------------| 

Render key von item.id:

|-----------------------|---------------------|--------------------------| 
| <Li key=1 val="A"> | <Li key=3 val="C"> | Moved from bottom to top | 
| <Li key=2 val="B"> | <Li key=2 val="B"> | None      | 
| <Li key=3 val="C"> | <Li key=1 val="A"> | Moved from top to bottom | 
|-----------------------|---------------------|--------------------------| 

Zusammenfassung: Sie immer id oder eine andere eindeutige Element-ID als key verwenden soll.

Siehe auch: https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318

+0

Dank, ich verstehe, was du meinst – 2014

0

Das Attribut "Schlüssel" wird von React verwendet, um zu bestimmen, ob eine brandneue Instanz der Komponente gerendert werden soll oder ob die Aktualisierung einer vorhandenen Instanz erfolgt. Wenn Sie also die Artikel-ID als Schlüssel verwenden, wird die Komponente für diesen Artikel nicht zerstört und neu erstellt. Wenn Sie der Liste ein neues Element hinzufügen, wird eine neue Komponente erstellt. Wenn Sie ein Element entfernen, wird das alte Element zerstört. Wenn Sie jedoch ein Element aktualisieren, ohne seine ID zu ändern, wird die Komponente nur aktualisiert.

Dies ist nützlich für dynamische Listen, da es merkwürdige Fälle reduziert, in denen eine gemountete Komponente vom Rendern eines Listenelements auf das Rendern eines anderen Listenelements umschaltet, obwohl es eigentlich eine brandneue Komponenteninstanz sein sollte.