Forståelse Reagerer `setState`

0
50

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

Reagerer komponenter med staten gjengi UI basert på at staten. Når staten komponenter endringer, så gjør UI komponent.

Som gjør forstå når og hvordan du endrer tilstanden din komponent viktig. På slutten av denne veiledningen, bør du vite hvordan setState fungerer, og være i stand til å unngå vanlige fallgruver som mange av oss hit når læring Reagere.

Arbeidet i `setState()`

setState() er den eneste legitime måten å oppdatere staten etter den første staten oppsett. La oss si vi har en søk-komponent, og ønsker å vise søkeordet en bruker sender.

Her er oppsettet:

import Reagere, { Komponent } fra “reagerer’

klasse Søk strekker seg Komponent {
constructor(props) {
super(props)

tilstand = {
searchTerm:”
}
}
}

Vi passerer en tom streng som en verdi, og for å oppdatere tilstand av searchTerm, vi må ringe setState().

setState({ searchTerm: event.målet.value })

Her er vi passerer et objekt for å setState(). Objektet inneholder en del av de statlige vi ønsker å oppdatere, som i dette tilfellet, er verdien av searchTerm. Reagerer tar denne verdien og fletter det inn i objektet som har behov for det. Det er liksom som å Søke komponent spør hva den skal bruke for verdien av searchTerm og setState() reagerer med et svar.

Dette er i utgangspunktet sparker i gang en prosess som Reagerer samtaler forsoning. Avstemming prosessen er måten du Reagerer oppdateringer DOM, ved å gjøre endringer for å component basert på endring i tilstand. Når forespørsel om å setState() aktiveres, Reagerer skaper en ny treet som inneholder reaktive elementer i komponenten (sammen med den oppdaterte staten). Dette treet er brukt til å finne ut hvordan Søke komponent UI bør endres i respons til staten endres ved å sammenligne det med elementer fra tidligere tre. Reagerer vet hvilke endringer for å implementere og vil bare oppdatere deler av DOM der det er nødvendig. Dette er grunnen til at du Reagerer raskt.

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

  • Vi har et søk komponent som viser et søkeord
  • At søkeordet er for øyeblikket tom
  • Brukeren sender en søketerm
  • Begrepet er fanget og lagret av setState som en verdi
  • Avstemming skjer og Reagerer merknader endringen i verdi
  • Reagerer instruerer søk-komponent for å oppdatere verdien og søkeordet er slått sammen i

Avstemming prosessen ikke nødvendigvis endre hele treet, bortsett fra i en situasjon hvor roten av treet er endret som dette:

// gamle
<div>
<Søk />
</div>

// ny
<span>
<Søk />
</span>

Alle <div> – kodene blir <span> – tager, og hele komponenten treet vil bli oppdatert som en følge av dette.

Den tommelfingerregel er å aldri mutere staten direkte. Bruk alltid setState() for å endre tilstand. Endring av staten direkte, som kodebiten nedenfor vil ikke føre komponent for å re-render.

// ikke gjør dette
dette.tilstand = {
searchTerm: event.målet.verdi
}

Passerer en Funksjon for å `setState()`

For å demonstrere denne ideen videre, la oss lage en enkel counter som intervaller, og reduserer på klikk.

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

La oss registrere komponent og angi markup for UI:

klasse App strekker seg til å Reagere.Komponent {

tilstand = { count: 0 }

handleIncrement = () => {
dette.setState({ count: dette.staten.teller + 1 })
}

handleDecrement = () => {
dette.setState({ count: dette.staten.teller – 1 })
}
render() {
retur (
<div>
<div>
{dette.staten.count}
</div>
<- knappen for onClick={dette.handleIncrement}>øker med 1</button>
<- knappen for onClick={dette.handleDecrement}>Minsk av 1</button>
</div>
)
}
}

På dette punktet, teller bare intervaller eller reduserer antallet av 1 på hvert klikk.

Men hva hvis vi ønsket å øke eller redusere med 3 i stedet? Vi kunne prøve å ringe setState() tre ganger i handleDecrement og handleIncrement funksjoner som dette:

handleIncrement = () => {
dette.setState({ count: dette.staten.teller + 1 })
dette.setState({ count: dette.staten.teller + 1 })
dette.setState({ count: dette.staten.teller + 1 })
}

handleDecrement = () => {
dette.setState({ count: dette.staten.teller – 1 })
dette.setState({ count: dette.staten.teller – 1 })
dette.setState({ count: dette.staten.teller – 1 })
}

Hvis du er koding sammen hjemme, vil du kanskje bli overrasket over å finne at det ikke fungerer.

Ovenfor kodebiten er tilsvarende til:

Objektet.tilordne(
{},
{ count: dette.staten.teller + 1 },
{ count: dette.staten.teller + 1 },
{ count: dette.staten.teller + 1 },
)

Objektet.tilordne() brukes til å kopiere data fra en kilde-objekt til et målobjekt. Hvis data blir kopiert fra kilden til målet alle har samme tastene, som i vårt eksempel, de siste objekt vinner. Her er en enklere versjon av hvordan Objektet.tilordne() fungerer;

la count = 3

const objekt = Objekt.tilordne({},
{count: ant + 1},
{count: ant + 2},
{count: ant + 3}
);

– konsollen.logg(objekt);
// utgang: Object { count: 6 }

Så i stedet for samtalen skjer tre ganger, det skjer bare en gang. Dette kan fikses ved å sende en funksjon for å setState(). Akkurat som du passerer objekter å setState(), kan du også passere funksjoner, og som er på vei ut av situasjonen ovenfor.

Hvis vi redigere handleIncrement funksjonen til å se ut som dette:

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

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

I dette tilfellet, i stedet for å flette, Reagerer køer funksjonen anrop i den rekkefølgen de er laget og oppdateringer hele staten som den er ferdig. Dette oppdateringer staten telle til 3 i stedet for 1.

Få Tilgang Til Tidligere Tilstand Ved Å Bruke Updater

Når du bygger Reagere programmer, det er tider når du får lyst til å beregne tilstand basert komponent tidligere tilstand. Du kan ikke alltid stole på dette.staten å holde riktig tilstand umiddelbart etter ringer setState(), så det er alltid like til staten gjengis på skjermen.

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

changeCount = () => {
dette.setState({ count: dette.staten.teller – 1})
}

Det vi ønsker er evnen til å øke med 3. Den changeCount () – funksjonen er kalt tre ganger i en funksjon som håndterer klikk hendelse som dette.

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

Hver gang knappen for å redusere klikkes, antall vil øke med 1 i stedet for 3. Dette er fordi dette.staten.teller ikke bli oppdatert til den komponenten som har blitt re-modellert. Løsningen er å bruke en updater. En updater, kan du få tilgang til nåværende tilstand og sette den til å bruke umiddelbart for å oppdatere andre elementer. Så changeCount () – funksjonen vil se sånn ut.

changeCount = () => {
dette.setState((prevState) => {
tilbake { count: prevState.teller – 1}
})
}

Nå er vi ikke avhengig av resultatet av denne.staten. Statene teller er bygget på hverandre, så vi er i stand til å få tilgang til riktig tilstand som endrer seg med hver samtale til changeCount().

setState() bør behandles asynkront — med andre ord, ikke alltid forvente at staten har endret seg etter ringer setState().

Innpakning Opp

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

  • Oppdateringen til en komponent staten bør gjøres ved hjelp av setState()
  • Du kan sende et objekt eller en funksjon for å setState()
  • Passere en funksjon når du kan å oppdatere tilstand flere ganger
  • Er ikke avhengig av dette.tilstand umiddelbart etter ringer setState() og gjøre bruk av den oppdaterte funksjonen i stedet.