Articles

Forstå React ‘setState’

React komponenter kan, og ofte gjør, har tilstand. Staten kan være noe, men tenk på ting som om en bruker er logget inn eller ikke, og viser riktig brukernavn basert på hvilken konto som er aktiv. Eller en rekke blogginnlegg. Eller om en modal er åpen eller ikke, og hvilken fane i den er aktiv.

React komponenter med tilstand gjengi UI basert på denne tilstanden. Når tilstanden til komponentene endres, gjør det også komponentgrensesnittet.

det gjør forståelse når og hvordan du endrer tilstanden til komponenten din viktig. På slutten av denne opplæringen bør du vite hvordan setState fungerer, og kunne unngå vanlige fallgruver som mange av oss treffer når vi lærer Å Reagere.

Arbeid av `setState ()`

setState() er den eneste legitime måten å oppdatere tilstand etter det opprinnelige tilstandsoppsettet. La oss si at vi har en søkekomponent og vil vise søkeordet en bruker sender inn.

her er oppsettet:

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

vi sender en tom streng som en verdi, og for å oppdatere tilstanden til searchTerm, må vi ringe setState().

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

her sender vi et objekt tilsetState(). Objektet inneholder delen av staten vi vil oppdatere, som i dette tilfellet er verdien av searchTerm. React tar denne verdien og fusjonerer den inn i objektet som trenger det. Det er liksom som Search komponenten spør hva den skal bruke for verdien av searchTerm og setState() svarer med et svar.

Dette er i utgangspunktet sparker av en prosess Som Reagerer kaller forsoning. Avstemmingsprosessen er Måten React oppdaterer DOM, ved å gjøre endringer i komponenten basert på endring i tilstand. Når forespørselen til setState() utløses, oppretter React et nytt tre som inneholder de reaktive elementene i komponenten(sammen med den oppdaterte tilstanden). Dette treet brukes til å finne ut hvordan Search komponentens BRUKERGRENSESNITT bør endres som svar på tilstandsendringen ved å sammenligne den med elementene i det forrige treet. React vet hvilke endringer som skal implementeres og vil bare oppdatere DELENE av DOM der det er nødvendig. Det Er Derfor Reagerer er rask.

det høres ut som mye, men for å oppsummere strømmen:

  • Vi har en søkekomponent som viser et søkeord
  • at søkeordet for øyeblikket er tomt
  • brukeren sender inn et søkeord
  • dette begrepet fanges opp og lagres av setState Som en verdi
  • Avstemming finner sted og React merknader endringen i verdi
  • React instruerer søkekomponenten til å oppdatere verdien og søkeordet er sammenslått i

avstemmingsprosessen endrer ikke nødvendigvis hele treet, unntatt i En Situasjon der roten av treet endres slik:

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

Alle <div> tagger blir <span> tagger og hele komponenttreet vil bli oppdatert som et resultat.

tommelfingerregelen er å aldri mutere staten direkte. Bruk alltid setState() for å endre tilstand. Endre tilstand direkte, som kodebiten nedenfor, vil ikke føre til at komponenten gjengis på nytt.

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

Passerer En Funksjon til ‘ setState ()`

for å demonstrere denne ideen videre, la oss lage en enkel teller som øker og avtar på klikk.

Se Pennen setState Penn av Kingsley Silas Chijioke (@kinsomicrote) På CodePen.

la oss registrere komponenten og definere markeringen for BRUKERGRENSESNITTET:

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

på dette punktet øker telleren bare eller reduserer tellingen med 1 på hvert klikk.

men hva om vi ønsket å øke eller redusere med 3 i stedet? Vi kunne prøve å ringesetState() tre ganger ihandleDecrement oghandleIncrement funksjoner som dette:

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

hvis du koder sammen hjemme, kan du bli overrasket over å finne at det ikke fungerer.

kodebiten ovenfor tilsvarer:

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

Object.assign() brukes til å kopiere data fra et kildeobjekt til et målobjekt. Hvis dataene som kopieres fra kilden til målet alle har samme nøkler, som i vårt eksempel, vinner det siste objektet. Her er en enklere versjon av hvordanObject.assign() fungerer;

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

så i stedet for at samtalen skjer tre ganger, skjer det bare en gang. Dette kan løses ved å sende en funksjon til setState(). Akkurat som du sender objekter til setState(), kan du også passere funksjoner, og det er veien ut av situasjonen ovenfor.

hvis vi redigererhandleIncrement funksjonen for å se slik ut:

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

…vi kan nå øke teller tre ganger med ett klikk.

I dette tilfellet, I stedet For å slå Sammen, React køer funksjonsanropene i den rekkefølgen de er laget og oppdaterer hele staten de er gjort. Dette oppdaterer tilstanden til antall til 3 i stedet for 1.

Få Tilgang Til Tidligere Tilstand Ved Hjelp Av Updater

når Du bygger React-programmer, er det tider når du vil beregne tilstand basert på komponentens tidligere tilstand. Du kan ikke alltid stole på this.state for å holde riktig tilstand umiddelbart etter å ha ringt setState(), da den alltid er lik tilstanden som er gjengitt på skjermen.

La oss gå tilbake til vårt tellereksempel for å se hvordan dette fungerer. La oss si at vi har en funksjon som reduserer vår telling med 1. Denne funksjonen ser slik ut:

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

det vi ønsker er evnen til å redusere med 3. changeCount() – funksjonen kalles tre ganger i en funksjon som håndterer klikkhendelsen, slik som dette.

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

hver gang knappen for å redusere klikkes, vil tellingen redusere med 1 i stedet for 3. Dette skyldes at this.state.count ikke blir oppdatert før komponenten er gjengitt på nytt. Løsningen er å bruke en oppdatering. En updater gir deg tilgang til gjeldende tilstand og sette den i bruk umiddelbart for å oppdatere andre elementer. SåchangeCount() – funksjonen vil se slik ut.

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

nå er Vi ikke avhengig av resultatet av this.state. Tilstandene count er bygget på hverandre, slik at vi kan få tilgang til riktig tilstand som endres med hvert anrop til changeCount().

setState() bør behandles asynkront — med andre ord, forvent ikke alltid at staten har endret seg etter å ha ringt setState().

Innpakning

når du arbeider med setState(), er dette de viktigste tingene du bør vite:

  • Oppdatering til en komponentstatus bør gjøres ved hjelp av setState()
  • Du kan sende et objekt eller en funksjon til setState()
  • pass en funksjon når du kan oppdatere tilstand flere ganger
  • ikke avhengig av dette.oppgi umiddelbart etter å ha ringt setState() og bruk oppdateringsfunksjonen i stedet.