Articles

A React `setState ‘ megértése

a React komponenseknek lehet, és gyakran van is állapotuk. Az állapot bármi lehet, de gondoljon például arra, hogy a felhasználó be van-e jelentkezve vagy sem, és megjelenítse a helyes felhasználónevet, amely alapján a fiók aktív. Vagy egy sor blogbejegyzés. Vagy ha egy Modál nyitva van,vagy sem, és melyik fül aktív.

React komponensek állapot render UI alapján, hogy az állam. Amikor az összetevők állapota megváltozik, akkor az összetevő felhasználói felülete is megváltozik.

Ez teszi annak megértését, hogy mikor és hogyan kell megváltoztatni az összetevő állapotát. A bemutató végén tudnia kell, hogyan működik a setState, és el kell kerülnie azokat a gyakori buktatókat, amelyeket sokan a tanulás során reagálnak.

A `setState ()`működése

setState() az egyetlen törvényes módja az állapot frissítésének a kezdeti állapotbeállítás után. Tegyük fel, hogy van egy keresési komponensünk, és meg akarjuk jeleníteni a felhasználó által beküldött keresési kifejezést.

itt van a Beállítás:

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

üres karakterláncot adunk át értékként, és asearchTermállapotának frissítéséhez fel kell hívnunk asetState() számot.

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

itt egy objektumot adunk átsetState(). Az objektum tartalmazza a frissíteni kívánt állapot azon részét, amely ebben az esetben a searchTermértéke. A React fogja ezt az értéket, és beolvasztja azt az objektumba, amelynek szüksége van rá. Ez olyan, mint a Search összetevő megkérdezi, hogy mit kell használni a searchTerm és setState() válaszra válaszol.

Ez alapvetően egy olyan folyamat elindítása, amely reagál a hívásokra. Az egyeztetési folyamat az, ahogyan a React frissíti a DOM-ot azáltal, hogy módosítja az összetevőt az állapotváltozás alapján. Amikor a setState() kérés elindul, a React létrehoz egy új fát, amely tartalmazza az összetevő reaktív elemeit (a frissített állapottal együtt). Ez a fa arra szolgál, hogy kitaláljuk, hogyan kell a Search komponens felhasználói felületének megváltoznia az állapotváltozásra válaszul, összehasonlítva azt az előző fa elemeivel. A React tudja, hogy mely változtatásokat kell végrehajtani, és csak szükség esetén frissíti a DOM részeit. Ezért gyors a reakció.

ez soknak hangzik, de összefoglalva az áramlást:

  • van egy keresési összetevő, amely megjeleníti a keresési kifejezést
  • ez a keresési kifejezés jelenleg üres
  • a felhasználó beküldi a keresési kifejezést
  • ezt a kifejezést a setState értékként
  • az egyeztetés megtörténik, és a React észreveszi az érték változását
  • a React utasítja a keresési összetevőt, hogy frissítse az értéket, és a keresési kifejezés összevonásra kerül ban ben

az egyeztetési folyamat nem feltétlenül változtatja meg az egész fát, kivéve abban az esetben, ha a fa gyökere így megváltozik:

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

minden <div>A címkék <span> címkévé válnak, és ennek eredményeként az egész komponensfa frissül.

a hüvelykujjszabály az, hogy soha ne mutálja közvetlenül az állapotot. Az állapot megváltoztatásához mindig használja a setState() elemet. Az állapot közvetlen módosítása, mint például az alábbi részlet, nem okozza az összetevő újbóli megjelenítését.

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

egy függvény átadása a `setState ()` – nek

az ötlet további bemutatásához hozzunk létre egy egyszerű számlálót, amely kattintással növekszik és csökken.

lásd Kingsley Silas Chijioke (@kinsomicrote) toll setState tollát a CodePen oldalon.

regisztráljuk az összetevőt, és határozzuk meg a felhasználói felület jelölését:

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

Ezen a ponton a számláló egyszerűen növeli vagy csökkenti a számlálást 1-gyel minden kattintáskor.

de mi lenne, ha inkább 3-mal szeretnénk növelni vagy csökkenteni? Megpróbálhatjuk hívni setState() háromszor a handleDecrement andhandleIncrement funkciók, mint ez:

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

ha otthon kódol, meglepődhet, hogy ez nem működik.

a fenti kódrészlet egyenértékű a következővel:

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

Object.assign() egy forrásobjektumból származó adatok célobjektumba történő másolására szolgál. Ha a forrásból a célba másolt adatok mindegyike azonos kulcsokkal rendelkezik, mint a példánkban, akkor az utolsó objektum nyer. Itt egy egyszerűbb változata, hogyanObject.assign() munkák;

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

tehát ahelyett, hogy a hívás történik háromszor, ez történik csak egyszer. Ezt úgy lehet rögzíteni, hogy egy függvényt átadunk a setState() – nek. Ahogy átadod az objektumokat a setState() – nek, a függvényeket is átadhatod, és ez a kiút a fenti helyzetből.

ha szerkesztjük a handleIncrement függvényt, hogy így nézzen ki:

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

…most már háromszor növelhetjük a számlálást egy kattintással.

ebben az esetben az egyesítés helyett a React sorba állítja a függvény hívásait a készítés sorrendjében, és frissíti a teljes állapotot. Ez frissíti az állam a gróf 3 helyett 1.

az előző állapot elérése az Updater használatával

a React alkalmazások felépítésekor vannak olyan esetek, amikor az összetevő előző állapota alapján szeretné kiszámítani az állapotot. Nem mindig bízhat abban, hogy a this.state hívás után azonnal megtartja a helyes állapotot setState(), mivel mindig megegyezik a képernyőn megjelenített állapottal.

térjünk vissza a számláló példánkhoz, hogy lássuk, hogyan működik ez. Tegyük fel, hogy van egy függvényünk, amely csökkenti a számunkat 1-gyel. Ez a funkció így néz ki:

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

azt akarjuk, hogy 3-mal csökkenjünk. AchangeCount() függvényt háromszor hívják meg egy olyan függvényben, amely kezeli a kattintási eseményt, mint ez.

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

minden alkalommal, amikor a csökkentés gombra kattint, a számlálás 1-gyel csökken 3 helyett. Ez azért van, mert a this.state.count nem frissül, amíg az összetevő újra nem lett renderelve. A megoldás egy frissítő használata. A frissítő lehetővé teszi az aktuális állapot elérését, és azonnal felhasználhatja más elemek frissítéséhez. Tehát a changeCount() függvény így fog kinézni.

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

most nem függünk athis.state eredményétől. A count állapotai egymásra épülnek, így képesek vagyunk elérni a helyes állapotot, amely minden híváskor changeCount()értékre változik.

setState()aszinkron módon kell kezelni — más szóval, nem mindig számíthat arra, hogy az állapot megváltozott a setState() hívás után.

becsomagolás

amikor dolgozik setState(), ezek a legfontosabb dolog, amit tudnod kell:

  • frissítés egy összetevő állapotban kell végezni a setState()
  • akkor át egy objektumot vagy függvényt setState()
  • adja át a funkciót, ha lehet frissíteni állapotban többször
  • nem függ ez.a setState() hívás után azonnal adja meg, és használja helyette a frissítő funkciót.