Articles

Înțelegerea React ‘ setState ‘

React componentele pot, și de multe ori fac, au stat. Starea poate fi orice, dar gândiți-vă la lucruri precum dacă un utilizator este conectat sau nu și afișarea numelui de utilizator corect pe baza contului activ. Sau o serie de postări pe blog. Sau dacă un modal este deschis sau nu și ce filă din acesta este activă.

React componente cu stare render UI bazat pe acea stare. Când starea componentelor se schimbă, la fel și interfața de utilizare a componentelor.

asta face importantă înțelegerea când și cum să schimbi starea componentei tale. La sfârșitul acestui tutorial, ar trebui să știți cum funcționează setState și să puteți evita capcanele comune pe care mulți dintre noi le lovim atunci când învățăm reacționează.

funcționarea”setState ()”

setState() este singura modalitate legitimă de a actualiza starea după configurarea inițială a stării. Să presupunem că avem o componentă de căutare și dorim să afișăm termenul de căutare pe care îl trimite un utilizator.

Iată configurarea:

import React, { Component } from 'react'class Search extends Component { constructor(props) { super(props) state = { searchTerm: '' } }}

trecem un șir gol ca valoare și, pentru a actualiza stareasearchTerm, trebuie să apelămsetState().

setState({ searchTerm: event.target.value })

aici, trecem un obiect lasetState(). Obiectul conține partea de stare pe care dorim să o actualizăm, care, în acest caz, este valoarea searchTerm. React ia această valoare și o îmbină în obiectul care are nevoie de ea. Este un fel de Search componenta întreabă ce ar trebui să folosească pentru valoarea searchTerm și setState() răspunde cu un răspuns.

aceasta este, practic, demararea unui proces care reacționează apeluri reconciliere. Procesul de reconciliere este modul în care React actualizează DOM, făcând modificări la componentă pe baza modificării stării. Când se declanșează solicitarea setState(), React creează un nou arbore care conține elementele reactive din componentă (împreună cu starea actualizată). Acest arbore este folosit pentru a afla cum Search UI componentă ar trebui să se schimbe ca răspuns la schimbarea de stat prin compararea cu elementele arborelui anterior. React știe ce modificări să implementeze și va actualiza doar părțile DOM acolo unde este necesar. Acesta este motivul pentru care reacționează rapid.

asta sună ca o mulțime, dar pentru a rezuma fluxul:

  • avem o componentă de căutare care afișează un termen de căutare
  • acel termen de căutare este momentan gol
  • utilizatorul trimite un termen de căutare
  • acel termen este capturat și stocat desetState ca valoare
  • reconcilierea are loc și React observă modificarea valorii
  • React instruiește componenta de căutare să actualizeze valoarea și termenul de căutare este îmbinat în

procesul de reconciliere nu schimbă neapărat întregul arbore, cu excepția unei situații în care rădăcina arborelui este schimbată astfel:

// old<div> <Search /></div>// new<span> <Search /></span>

toate<div> etichetele devin<span> etichetele și întregul arbore component vor fi actualizate ca rezultat.

regula generală este de a nu muta niciodată starea direct. Utilizați întotdeauna setState() pentru a schimba starea. Modificarea stării direct, cum ar fi fragmentul de mai jos nu va determina re-Redarea componentei.

// do not do thisthis.state = { searchTerm: event.target.value}

trecerea unei funcții la `setState ()`

pentru a demonstra mai departe această idee, să creăm un contor simplu care crește și scade la clic.

a se vedea Pen setState Pen de Kingsley Silas Chijioke (@kinsomicrote) pe CodePen.

să înregistrăm componenta și să definim marcajul pentru UI:

class App extends React.Component {state = { count: 0 }handleIncrement = () => { this.setState({ count: this.state.count + 1 })}handleDecrement = () => { this.setState({ count: this.state.count - 1 })} render() { return ( <div> <div> {this.state.count} </div> <button onClick={this.handleIncrement}>Increment by 1</button> <button onClick={this.handleDecrement}>Decrement by 1</button> </div> ) }}

în acest moment, contorul pur și simplu crește sau scade numărul cu 1 la fiecare clic.

dar dacă am vrea să creștem sau să scădem cu 3 în schimb? Am putea încerca să apelăm setState() de trei ori în handleDecrement și handleIncrement funcții ca aceasta:

handleIncrement = () => { this.setState({ count: this.state.count + 1 }) this.setState({ count: this.state.count + 1 }) this.setState({ count: this.state.count + 1 })}handleDecrement = () => { this.setState({ count: this.state.count - 1 }) this.setState({ count: this.state.count - 1 }) this.setState({ count: this.state.count - 1 })}

dacă sunteți de codificare de-a lungul la domiciliu, s-ar putea fi surprins să afle că nu funcționează.

fragmentul de cod de mai sus este echivalent cu:

Object.assign( {}, { count: this.state.count + 1 }, { count: this.state.count + 1 }, { count: this.state.count + 1 },)

Object.assign() este folosit pentru a copia date dintr-un obiect sursă într-un obiect țintă. Dacă datele copiate de la sursă la țintă au toate aceleași chei, ca în exemplul nostru, ultimul obiect câștigă. Iată o versiune mai simplă a modului în careObject.assign() funcționează;

let count = 3const object = Object.assign({}, {count: count + 1}, {count: count + 2}, {count: count + 3});console.log(object);// output: Object { count: 6 }

Deci, în loc ca apelul să se întâmple de trei ori, se întâmplă o singură dată. Acest lucru poate fi remediat prin trecerea unei funcții la setState(). La fel cum treceți obiecte la setState(), puteți trece și funcții și aceasta este calea de ieșire din situația de mai sus.

dacă editămhandleIncrement funcția pentru a arăta astfel:

handleIncrement = () => { this.setState((prevState) => ({ count: prevState.count + 1 })) this.setState((prevState) => ({ count: prevState.count + 1 })) this.setState((prevState) => ({ count: prevState.count + 1 }))}

…acum putem crește numărul de trei ori cu un singur clic.

în acest caz, în loc să fuzioneze, React cozi apelurile de funcții în ordinea în care sunt făcute și actualizează întreaga stare Cele se face. Aceasta actualizează starea de numărare la 3 în loc de 1.

accesați starea anterioară folosind Updater

când construiți aplicații React, există momente în care veți dori să calculați starea pe baza stării anterioare a componentei. Nu puteți avea întotdeauna încredere în this.state pentru a menține starea corectă imediat după apelarea setState(), deoarece este întotdeauna egală cu starea redată pe ecran.

să ne întoarcem la exemplul nostru contra pentru a vedea cum funcționează acest lucru. Să presupunem că avem o funcție care scade numărul nostru cu 1. Această funcție arată astfel:

changeCount = () => { this.setState({ count: this.state.count - 1})}

ceea ce ne dorim este capacitatea de a decrementa cu 3. FuncțiachangeCount() este apelată de trei ori într-o funcție care gestionează evenimentul de clic, astfel.

handleDecrement = () => { this.changeCount() this.changeCount() this.changeCount()}

de fiecare dată când se face clic pe butonul de reducere, numărul va scădea cu 1 în loc de 3. Acest lucru se datorează faptului că this.state.count nu se actualizează până când componenta nu a fost redată. Soluția este să folosiți un actualizator. Un actualizator vă permite să accesați starea curentă și să o utilizați imediat pentru a actualiza alte elemente. Deci, funcția changeCount() va arăta astfel.

changeCount = () => { this.setState((prevState) => { return { count: prevState.count - 1} })}

acum nu depindem de rezultatulthis.state. Stările countsunt construite una pe cealaltă, astfel încât să putem accesa starea corectă care se schimbă cu fiecare apel lachangeCount().

setState() ar trebui să fie tratate asincron — cu alte cuvinte, nu se așteaptă întotdeauna că starea sa schimbat după apelareasetState().

împachetarea

când lucrați cu setState(), acestea sunt lucrurile majore pe care ar trebui să le cunoașteți:

  • actualizarea la o stare componentă trebuie făcută folosind setState()
  • puteți trece un obiect sau o funcție la setState()
  • treceți o funcție atunci când puteți să actualizați starea de mai multe ori
  • nu depind de acest lucru.stat imediat după apelarea setState() și să facă uz de funcția updater în schimb.