Articles

Ymmärrysreaktiolla ”setState”

Reaktiokomponenteilla voi ja usein onkin tila. Tila voi olla mitä tahansa, mutta ajattele asioita, kuten onko käyttäjä kirjautunut sisään vai ei ja näyttää oikean käyttäjätunnuksen sen perusteella, mikä tili on aktiivinen. Tai joukko blogikirjoituksia. Tai jos modaali on auki tai ei ja mikä välilehti sen sisällä on aktiivinen.

reagoivat komponentit, joiden tila renderöi UI: n tämän tilan perusteella. Kun komponenttien tila muuttuu, myös komponentin käyttöliittymä muuttuu.

tämän vuoksi on tärkeää ymmärtää, milloin ja miten komponentin tilaa muutetaan. Tämän opetusohjelman lopussa pitäisi tietää, miten setState toimii, ja osata välttää yhteiset sudenkuopat, joihin moni meistä osuu, Kun oppiminen reagoi.

”setState ()”

setState() on ainoa laillinen tapa päivittää tila alkutilan jälkeen. Sanotaan, että meillä on hakukomponentti ja haluamme näyttää hakutermin, jonka käyttäjä lähettää.

tässä kokoonpano:

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

ohitamme tyhjän merkkijonon arvona ja searchTerm tilan päivittämiseksi on soitettava setState().

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

tässä ohitamme kohteen setState(). Objekti sisältää sen osan tilasta, jonka haluamme päivittää, joka tässä tapauksessa on arvo searchTerm. React ottaa tämän arvon ja yhdistää sen sitä tarvitsevaan kohteeseen. Se on vähän niin kuin Search komponentti kysyy, mitä sen pitäisi käyttää arvolle searchTerm ja setState() vastaa vastauksella.

tämä käytännössä käynnistää prosessin, jossa reagoidaan sovintoon. Täsmäytysprosessi on tapa, jolla React päivittää DOM: n tekemällä muutoksia komponenttiin tilan muutoksen perusteella. Kun pyyntö setState() käynnistyy, React luo uuden puun, joka sisältää komponentin reaktiiviset elementit (yhdessä päivitetyn tilan kanssa). Tätä puuta käytetään selvittämään, miten Search komponentin käyttöliittymän tulisi muuttua vastauksena tilan muutokseen vertaamalla sitä edellisen puun elementteihin. React tietää, mitkä muutokset on toteutettava ja päivittää DOM: n osia vain tarvittaessa. Siksi reagointi on nopeaa.

tuo kuulostaa paljolta, mutta kiteyttää virtauksen:

  • meillä on hakukomponentti, joka näyttää hakukomponentin
  • että hakukomponentti on tällä hetkellä tyhjä
  • käyttäjä lähettää hakukomponentin
  • että setState arvona
  • täsmäytys tapahtuu ja reagoi huomaa arvon muutoksen
  • React ohjeistaa hakukomponenttia päivittämään arvon ja hakutermi on yhdistyminen

täsmäytysprosessi ei välttämättä muuta koko puuta, paitsi tilanteessa, jossa puun juurta muutetaan näin:

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

kaikki <div> tagit muuttuvat <span> tageiksi ja koko komponenttipuu päivitetään tämän seurauksena.

nyrkkisääntönä on, ettei koskaan mutatoida tilaa suoraan. Käytä aina setState() muuttaaksesi tilaa. Muokkaamalla tila suoraan, kuten katkelma alla ei aiheuta komponentin uudelleen renderöidä.

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

siirtää Funktion ”setState ()”

osoittaakseen tämän idean edelleen, luodaan yksinkertainen laskuri, joka increments and decrements on click.

See the Pen settstate Pen by Kingsley Silas Chijioke (@kinsomicrote) on CodePen.

rekisteröidään komponentti ja määritellään käyttöliittymä:

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

tässä vaiheessa laskuri yksinkertaisesti lisää tai pienentää lukua 1: llä jokaisella klikkauksella.

mutta mitä jos haluaisimmekin lisätä tai säätää 3: lla sen sijaan? Voisimme yrittää kutsua setState() kolme kertaa handleDecrement ja handleIncrement funktioita näin:

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

Jos koodaat kotona, saatat yllättyä huomatessasi, ettei se toimi.

yllä olevaa koodinpätkää vastaa:

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

Object.assign() käytetään tietojen kopioimiseen lähdeobjektista kohdeobjektiin. Jos lähteestä kohteeseen kopioitavilla tiedoilla on kaikilla samat avaimet, kuten esimerkissämme, viimeinen objekti voittaa. Tässä yksinkertaisempi versio siitä, miten Object.assign() toimii;

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

joten sen sijaan, että puhelu tapahtuisi kolme kertaa, se tapahtuu vain kerran. Tämä voidaan vahvistaa siirtämällä funktio setState(). Aivan kuten ohitat objekteja setState(), voit myös siirtää funktioita, ja se on tie ulos yllä olevasta tilanteesta.

Jos muokkaamme handleIncrement funktion näyttämään tältä:

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

…voimme nyt lisätä määrän kolme kertaa yhdellä klikkauksella.

tässä tapauksessa yhdistämisen sijaan React jonottaa funktiokutsut siinä järjestyksessä kuin ne on tehty ja päivittää koko tilan ne on tehty. Tämä päivittää tilan count 3 sijasta 1.

käytä edellistä tilaa Päivittäjällä

kun rakennat React-sovelluksia, on aikoja, jolloin haluat laskea tilan komponentin edellisen tilan perusteella. Aina ei voi luottaa this.state pitämään oikeaa tilaa heti soiton jälkeen setState(), koska se on aina yhtä suuri kuin ruudulla renderoitu tila.

palataan vastaesimerkkiimme ja katsotaan, miten tämä toimii. Oletetaan, että meillä on funktio, joka määrää laskumme 1: llä. Tämä funktio näyttää tältä:

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

se, mitä haluamme, on kyky säätää 3. changeCount() funktiota kutsutaan kolme kertaa funktioksi, joka käsittelee klikkaustapahtuman, näin.

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

joka kerta, kun säätöpainiketta napsautetaan, määrä määrää 1: n sijasta 3. Tämä johtuu siitä, että this.state.count ei päivity ennen kuin komponentti on renderöity uudelleen. Ratkaisu on käyttää updater. Päivitysohjelman avulla voit käyttää nykyistä tilaa ja käyttää sitä välittömästi muiden kohteiden päivittämiseen. Niinpä changeCount() funktio näyttää tältä.

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

nyt emme ole riippuvaisia this.statetuloksesta. count valtiot rakentuvat toistensa varaan, joten pääsemme käsiksi oikeaan tilaan, joka muuttuu jokaisen kutsun myötä changeCount().

setState() tulee hoitaa asynkronisesti — eli ei aina pidä olettaa, että tila on muuttunut soitettuaan setState().

paketointi

kun työskentelet setState(), nämä ovat tärkeimmät asiat, jotka sinun tulisi tietää:

  • päivitys komponenttitilaan tulisi tehdä käyttämällä setState()
  • voit siirtää objektin tai funktion setState()
  • ohita funktio, kun voit päivittää tilan useita kertoja
  • älä riipu tästä.ilmoita heti soiton jälkeen setState() ja käytä sen sijaan päivitystoimintoa.