de Christoph Michel

Cum funcționează tastele React și lucrurile distractive pe care le puteți face cu ele

Cum functioneaza tastele React si lucrurile distractive pe care le

React folosește key atribut în timpul faza sa de reconciliere să decidă care elemente poate fi reutilizat pentru următorul randare. Acestea sunt importante pentru listele dinamice. React va compara cheile noului element cu tastele anterioare și 1) montează componente care au o cheie nouă 2) demontează componentele ale căror chei nu mai sunt folosite.

Mulți dezvoltatori React au auzit sfatul general pe care îl aveți nu ar trebui să folosească index ca cheie. Dar ce anume poate merge prost când se folosește keye într-un mod rău? Ce altceva putem face când ne jucăm cu tastele?

Pentru o mai bună înțelegere, să luăm în considerare exemplul de redare a unei liste de inputs. Când faceți clic pe un buton, vom introduce un nou articol cu ​​text Front in fata a listei.

import React from "react";import { render } from "react-dom";class Item extends React.PureComponent {  state = {    text: this.props.text  };  onChange = event => {    this.setState({      text: event.target.value    });  };  componentDidMount() {    console.log("Mounted ", this.props.text);  }  componentWillUnmount() {    console.log("Unmounting ", this.props.text);  }  render() {    console.log("rerendering ", this.props.text);    const { text } = this.state;    return (      <li>        <input value={text} onChange={this.onChange} />      </li>    );  }}class App extends React.Component {  state = {    items: [      {        text: "First",        id: 1      },      {        text: "Second",        id: 2      }    ]  };  addItem = () => {    const items = [{ text: "Front", id: Date.now() }, ...this.state.items];    this.setState({ items });  };  render() {    return (      <div>        <ul>          {this.state.items.map((item, index) => (            <Item {...item} key={index} />          ))}        </ul>        <button onClick={this.addItem}>Add Item</button>      </div>    );  }}render(<App />, document.getElementById("root"));

Dacă folosești index ca cheie, se întâmplă următoarele:

CodeSandbox
CodeSandbox este un editor online adaptat pentru aplicații web.codesandbox.io

Cum functioneaza tastele React si lucrurile distractive pe care le

Dacă altul Item cu text Second in loc de Front este inserat in spate a listei? Iată ce se întâmplă:

  1. Item is an uncontrolled component: Textul pe care utilizatorul îl scrie în input câmpul este stocat ca state
  2. Un nou element de date { text: "Front" } este inserat la începutul datelor din listă.
  3. Lista este redată cu index valoare ca key. Deci, componentele anterioare sunt refolosite pentru primele două elemente de date și li se oferă recuzita corectă Front și First, dar statul nu este actualizat în Item. De aceea primele două instanțe componente păstrează același text.
  4. O nouă instanță componentă este creată pentru key: 2 deoarece nu a fost găsită nicio cheie de potrivire anterioară. Este umplut cu props din ultima lista de date care este Second.
Cum functioneaza tastele React si lucrurile distractive pe care le

Un alt punct interesant este render apeluri care se întâmplă. Elementul este un PureComponent, deci se actualizează numai atunci când text modificări ale propunerii (sau stării):

rerendering  Frontrerendering  Firstrerendering  SecondMounted  Second

Toate componentele sunt redate. Acest lucru se întâmplă deoarece elementul cu key: 0 este reutilizat pentru primul articol de date și primește props, dar primul element de date este acum nou Front obiect, declanșând un render. La fel se întâmplă și cu celelalte componente, deoarece elementele de date vechi sunt acum deplasate într-un singur loc.

Deci, care este soluția? Remedierea este ușoară: oferim fiecărui element de listă un element unic id o data la creație (nu pe fiecare randare!). Toate instanțele componentelor vor fi potrivite cu elementul lor de date corespunzător. Ei primesc la fel props ca și înainte, iar acest lucru evită altul render.

Să ignorăm beneficiile de performanță care rezultă din utilizarea ids în liste dinamice pentru moment. Exemplul arată că erorile introduse de chei se întâmplă numai în ceea ce privește necontrolat componente, componente care se păstrează starea internă.

Dacă rescriem Item ca o componentă controlată, prin mutarea stării din ea, bug-ul a dispărut.

De ce? Din nou, pentru că bug-ul a fost refolosirea unei componente pentru un alt element de date. Prin urmare, starea internă încă a reflectat starea elementului de date anterior, cu exceptia recuzită de altul. Controlând componenta, eliminându-i complet starea, nu mai avem această discrepanță. (Dar există încă problema reluărilor inutile.)

Abuzarea tastelor pentru remedierea componentelor terță parte

Reacționează doar nevoile keys când se potrivesc mai multe elemente, deci nu este necesară setarea unei chei pe un singur copil. Dar poate fi totuși util să setați o cheie pe o singură componentă copil.

Dacă schimbați cheia, React va arunca întreaga componentă (o va demonta) și va monta o nouă instanță de componentă în locul ei. De ce ar putea fi util acest lucru?

Din nou, ne întoarcem la componente necontrolate. Uneori, utilizați o componentă terță parte și nu îi puteți modifica codul pentru a-l controla. Dacă o componentă are o anumită stare internă și este implementată într-un mod prost (de exemplu, starea este derivată numai o singura data în constructor, dar getDerivedStateFromProps / componentWillReceiveProps nu este implementat în reflectă reapariția props modificări ale stării sale interne), setul de instrumente standard React nu vă poate ajuta aici. Nu este forceRemount.

Cu toate acestea, putem seta doar un nou key pe această componentă pentru a realiza comportamentul dorit de inițializare completă a unei noi componente. Vechea componentă va fi demontată, iar una nouă va fi montată împreună cu noua props inițializarea state.

TL; DR:

Folosind index ca cheie poate:

  1. să conducă la redări inutile
  2. introduceți erori când sunt elementele listei componente necontrolate dar totusi folositi props

key proprietatea poate fi folosită pentru a forța o remontare completă a unei componente, care uneori poate fi utilă.

Publicat inițial la cmichel.io

1611463866 724 Cum functioneaza tastele React si lucrurile distractive pe care le