Ein Hinweis, wie React den Status aktualisiert





Guten Tag, Freunde!



Der useState () - Hook verwaltet den Status in React-Funktionskomponenten. In Class Beans wird state in this.state gespeichert und die Methode this.setState () wird zum Aktualisieren aufgerufen.



Normalerweise ist es nicht schwierig, mit dem Staat zu arbeiten. Mit der Aktualisierung ist jedoch eine wichtige Nuance verbunden.



Wie wird der Status aktualisiert: sofort (synchron) oder zurückgestellt (asynchron)? Lesen Sie weiter, um die Antwort herauszufinden.



1. Aktualisieren des Status mit useState ()



Nehmen wir an, wir haben eine solche funktionale Komponente:



import { useState } from 'react'

function DoubleIncreaser() {
  const [count, setCount] = useState(0)

  const doubleIncreaseHandler = () => {
    setCount(count + 1)
    setCount(count + 1)
  }

  return (
    <>
      <button onClick={doubleIncreaseHandler}>
        Double Increase
      </button>
      <div>Count: {count}</div>
    </>
  )
}

      
      





const [count, setCount] = useState (0) definiert den Anfangszustand der Komponente. count ist eine Variable, die den aktuellen Status enthält, und setCount ist eine Funktion zum Aktualisieren dieses Status.



Die Komponente enthält eine Schaltfläche zum doppelten Erhöhen. Wenn Sie auf diese Schaltfläche klicken, wird der doubleIncreaseHandler-Handler aufgerufen, der zwei aufeinanderfolgende Aktualisierungen durchführt, um zu zählen: setCount (count + 1) und dann setCount (count + 1) erneut.



Wie ist der Status der Komponente nach dem Klicken auf die Schaltfläche 1 oder 2?



Öffnen Sie diese Demo und klicken Sie auf die Schaltfläche. Der Zählwert erhöht sich nach jedem Klick um 1.



Wenn setCount (count + 1) den Status aktualisiert, ändert sich der Zählwert nicht sofort. Stattdessen plant React den zu aktualisierenden Status und beim nächsten Rendern setzt der Hook in const [count, setCount] = useState (0) die Anzahl auf einen neuen Wert.



Beispiel: Wenn der Wert der Variablen count 0 ist, rufen Sie setCount (count + 1) auf. setCount (count + 1) ergibt setCount (0 + 1); setCount (0 + 1) - Dies ergibt 1 als Statuswert beim nächsten Rendern.



Daher erfolgt die Aktualisierung des Status mit setValue (newValue) in [value, setValue] = useState () asynchron.



Die Statusaktualisierungsfunktion kann jedoch einen Rückruf als Argument verwenden, um einen neuen Status basierend auf dem aktuellen zu berechnen. In unserem Fall können wir setCount verwenden (actualCount => actualCount + 1):



import { useState } from 'react'

function DoubleIncreaser() {
  const [count, setCount] = useState(0)

  const doubleIncreaseHandler = () => {
    setCount(actualCount => actualCount + 1)
    setCount(actualCount => actualCount + 1)
  }

  return (
    <>
      <button onClick={doubleIncreaseHandler}>
        Double Increase
      </button>
      <div>Count: {count}</div>
    </>
  )
}

      
      





Wenn Sie den Status mit dieser Funktion aktualisieren, enthält das Argument actualCount den tatsächlichen Statuswert.



Öffnen Sie diese Demo und klicken Sie auf die Schaltfläche. Die Anzahl wird wie erwartet auf 2 erhöht.



Natürlich können wir immer eine Zwischenvariable erstellen:



import { useState } from 'react'

function DoubleIncreaser() {
  const [count, setCount] = useState(0)

  const doubleIncrease = () => {
    let actualCount = count
    actualCount = actualCount + 1
    actualCount = actualCount + 1
    setCount(actualCount)
  }

  return (
    <>
      <button onClick={this.doubleIncrease}>
        Double Increase
      </button>
      <div>Count: {count}</div>
    </>
  )
}

      
      





let actualCount = count ist eine Zwischenvariable, die Sie nach Belieben aktualisieren können. Diese Variable wird verwendet, um den Status mit setCount (actualCount) zu aktualisieren.



2. Der Zustand ist unveränderlich (unveränderlich) und schreibgeschützt



Wenn Sie vergessen, dass der Status beim nächsten Rendern aktualisiert wird, können Sie versuchen, den Wert direkt nach seiner Änderung zu lesen. Leider bekommen Sie nichts:



function FetchUsers() {
  const [users, setUsers] = useState([])

  useEffect(() => {
    const startFetching = async () => {
      const response = await fetch('/users')
      const fetchedUsers = await response.json()

      setUsers(fetchedUsers)
      console.log(users)        // => []
      console.log(fetchedUsers) // => ['John', 'Jane', 'Alice', 'Bob']
    }
    startFetching()
  }, [])

  return (
    <ul>
      {users.map(user => <li>{user}</li>)}
    </ul>
  )
}

      
      





Die FetchUsers-Komponente sendet eine Mount-Anforderung - startFetching ().



Wenn Daten empfangen werden, aktualisiert setUsers (fetchedUsers) den Status. Änderungen finden jedoch nicht über Nacht statt.



Die Benutzervariable ist unveränderlich und schreibgeschützt. Nur der Hook useState () kann ihm einen neuen Wert zuweisen. Sie können dies nicht direkt tun:



  function FetchUsers() {
    const [users, setUsers] = useState([])

    useEffect(() => {
      const startFetching = async () => {
        const response = await fetch('/users')
        const fetchedUsers = await response.json()

        users = fetchedUsers       // ! users    
        users.push(...fetchedUsers) // ! users 
        setUsers(fetchedUsers)     // !
      }
      startFetching()
    }, [])

    return (
      <ul>
        {users.map(user => <li>{user}</li>)}
      </ul>
    )
  }

      
      





3. Aktualisieren des Status in der Klassenkomponente



Asynchrone Statusaktualisierungen sind für Klassenkomponenten üblich.



Betrachten wir ein Beispiel:



import { Component } from 'react';

class DoubleIncreaser extends Component {
  state = {
    count: 0
  };

  render() {
    return (
      <>
        <button onClick={this.doubleIncrease}>
          Double Increase
        </button>
        <div>Count: {this.state.count}</div>
      </>
    );
  }

  doubleIncrease = () => {
    // !
    this.setState(({ count }) => ({
      count: count + 1
    }));
    this.setState(({ count }) => ({
      count: count + 1
    }));

    //  !
    // this.setState({ count: this.state.count + 1 });
    // this.setState({ count: this.state.count + 1 });
  }
}

      
      





Beachten Sie den doubleIncrease () -Handler: Er verwendet eine Rückruffunktion, um den Status zu aktualisieren.



Öffnen Sie diese Demo und klicken Sie auf die Schaltfläche. Der Wert von this.state wird auf 2 erhöht.



In Klassenkomponenten wird this.state auch nicht sofort aktualisiert. Wenn this.setState (newState) aufgerufen wird, verzögert React die Aktualisierung dieses Status bis zum nächsten Rendern.



Daher aktualisiert this.setState (newState) diesen Status asynchron.



4. Fazit



Der useState () - Hook und this.setState () (innerhalb der Klassenkomponente) aktualisieren den Variablenwert und den Komponentenstatus asynchron.



Denken Sie an eine einfache Regel: Wenn Sie den Setter setState (newValue) des Hooks useState () (oder this.setState ()) aufrufen, wird der Status nicht sofort aktualisiert, sondern beim nächsten Rendern der Komponente.



Haben Sie bemerkt, dass React jetzt nur noch einmal importiert werden muss (in index.js)? Dies ist in den Komponenten nicht mehr erforderlich.



Vielen Dank für Ihre Aufmerksamkeit und einen schönen Tag.



All Articles