Was ist useState () in React?


133

Ich lerne gerade das Hooks-Konzept in React und versuche, das folgende Beispiel zu verstehen.

import { useState } from 'react';

function Example() {
    // Declare a new state variable, which we'll call "count"
    const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Das obige Beispiel erhöht den Zähler im Handlerfunktionsparameter selbst. Was ist, wenn ich den Zählwert innerhalb der Ereignishandlerfunktion ändern möchte?

Betrachten Sie das folgende Beispiel

setCount = () => {
  //how can I modify count value here. Not sure if I can use setState to modify its value
  //also I want to modify other state values as well here. How can I do that
}

<button onClick={() => setCount()}>
  Click me
</button>

Sie können auch im Quellcode nachsehen, wie useStatedie Implementierung erfolgt. Hier ist die Definition ab Version 16.9 .
Chemturion

Antworten:


148

React Hooks sind eine neue (noch in der Entwicklung befindliche) Möglichkeit, auf die Kernfunktionen von React zuzugreifen, z. B. stateohne Klassen verwenden zu müssen. In Ihrem Beispiel möchten Sie einen Zähler direkt in der Handler-Funktion erhöhen, ohne ihn direkt in der onClickRequisite anzugeben könnte so etwas tun wie:

...
const [count, setCounter] = useState(0);
const [moreStuff, setMoreStuff] = useState(...);
...

const setCount = () => {
    setCounter(count + 1);
    setMoreStuff(...);
    ...
};

und onClick:

<button onClick={setCount}>
    Click me
</button>

Lassen Sie uns kurz erklären, was in dieser Zeile vor sich geht:

const [count, setCounter] = useState(0);

useState(0)Gibt ein Tupel zurück, bei dem der erste Parameter countder aktuelle Status des Zählers ist und setCounterdie Methode ist, mit der wir den Status des Zählers aktualisieren können. Wir können die setCounterMethode verwenden, um den Status von countüberall zu aktualisieren. In diesem Fall verwenden wir sie innerhalb der setCountFunktion, in der wir mehr tun können. Die Idee mit Hooks ist, dass wir unseren Code funktionsfähiger halten und klassenbasierte Komponenten vermeiden können wenn dies nicht gewünscht / benötigt wird.

Ich schrieb einen kompletten Artikel über Haken mit mehreren Beispielen (einschließlich Zähler) wie diese codepen , benutzte ich useState, useEffect, useContextund individuelle Haken . Ich könnte näher auf die Funktionsweise von Hooks bei dieser Antwort eingehen, aber die Dokumentation erklärt den Status-Hook sehr gut und andere Hooks im Detail. hoffe, es hilft.

Update: Hooks sind nicht länger ein Vorschlag , ab Version 16.8 sie jetzt verfügbar sind verwendet werden, gibt es einen Abschnitt in React Website , dass die Antworten einige der FAQ .


2
Gute Analogie, außer dass JavaScript technisch gesehen keinen Tupel-Datentyp hat
goonerify

Nun, die zerstörte Zuweisung wird wie Tupel stackoverflow.com/a/4513061/6335029
NaveenDA

Sind Hooks asynchron? Wenn setSomethingich es dann somethingdirekt danach versuche , scheint es immer noch den alten Wert zu haben ...
Byron Coetsee

51

useState ist einer der eingebauten Reaktionshaken, die in verfügbar sind 0.16.7 Version .

useStatesollte nur innerhalb von Funktionskomponenten verwendet werden. useStateDies ist der Weg, wenn wir einen internen Zustand benötigen und keine komplexere Logik wie Lebenszyklusmethoden implementieren müssen.

const [state, setState] = useState(initialState);

Gibt einen statusbehafteten Wert und eine Funktion zum Aktualisieren zurück.

Während des ersten Renderns entspricht der zurückgegebene Status (Status) dem Wert, der als erstes Argument (initialState) übergeben wurde.

Mit der Funktion setState wird der Status aktualisiert. Es akzeptiert einen neuen Statuswert und stellt ein erneutes Rendern der Komponente in die Warteschlange.

Bitte beachten Sie, dass sich der useStateHook-Rückruf zum Aktualisieren des Status anders verhält als Komponenten this.setState. Um Ihnen den Unterschied zu zeigen, habe ich zwei Beispiele vorbereitet.

class UserInfoClass extends React.Component {
  state = { firstName: 'John', lastName: 'Doe' };
  
  render() {
    return <div>
      <p>userInfo: {JSON.stringify(this.state)}</p>
      <button onClick={() => this.setState({ 
        firstName: 'Jason'
      })}>Update name to Jason</button>
    </div>;
  }
}

// Please note that new object is created when setUserInfo callback is used
function UserInfoFunction() {
  const [userInfo, setUserInfo] = React.useState({ 
    firstName: 'John', lastName: 'Doe',
  });

  return (
    <div>
      <p>userInfo: {JSON.stringify(userInfo)}</p>
      <button onClick={() => setUserInfo({ firstName: 'Jason' })}>Update name to Jason</button>
    </div>
  );
}

ReactDOM.render(
  <div>
    <UserInfoClass />
    <UserInfoFunction />
  </div>
, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>

Neues Objekt wird erstellt, wenn setUserInfoRückruf verwendet wird. Beachten Sie, dass wir den lastNameSchlüsselwert verloren haben. Um das zu beheben, konnten wir die Funktion im Inneren übergeben useState.

setUserInfo(prevState => ({ ...prevState, firstName: 'Jason' })

Siehe Beispiel:

// Please note that new object is created when setUserInfo callback is used
function UserInfoFunction() {
  const [userInfo, setUserInfo] = React.useState({ 
    firstName: 'John', lastName: 'Doe',
  });

  return (
    <div>
      <p>userInfo: {JSON.stringify(userInfo)}</p>
      <button onClick={() => setUserInfo(prevState => ({
        ...prevState, firstName: 'Jason' }))}>
        Update name to Jason
      </button>
    </div>
  );
}

ReactDOM.render(
    <UserInfoFunction />
, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>

Im Gegensatz zur setState-Methode in Klassenkomponenten führt useState Aktualisierungsobjekte nicht automatisch zusammen. Sie können dieses Verhalten replizieren, indem Sie das Funktionsaktualisierungsformular mit der Objektverbreitungssyntax kombinieren:

setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});

Weitere Informationen finden useStateSie in der offiziellen Dokumentation .


2
Vielen Dank, dass Sie im Beispiel eine Funktion als Parameter hinzugefügt haben.
Juni Brosas

15

Die Syntax von useStatehook ist unkompliziert.

const [value, setValue] = useState(defaultValue)

Wenn Sie mit dieser Syntax nicht vertraut sind, klicken Sie hier .

Ich würde Ihnen empfehlen, die Dokumentation zu lesen. Es gibt ausgezeichnete Erklärungen mit einer anständigen Anzahl von Beispielen.

import { useState } from 'react';

function Example() {
    // Declare a new state variable, which we'll call "count"
    const [count, setCount] = useState(0);
  
  // its up to you how you do it
  const buttonClickHandler = e => {
   // increment
   // setCount(count + 1)
   
   // decrement
   // setCount(count -1)
   
   // anything
   // setCount(0)
  }
  

  return (
       <div>
          <p>You clicked {count} times</p>
         <button onClick={buttonClickHandler}>
             Click me
         </button>
      </div>
   );
 }


Dies sollte die akzeptierte Antwort sein. Prägnant und klar, mit guten externen Referenzen.
Varun

8

useStateist einer der in React v16.8.0 verfügbaren Hooks. Grundsätzlich können Sie Ihre ansonsten nicht zustandsbehafteten / funktionalen Komponenten in eine Komponente umwandeln, die einen eigenen Zustand haben kann.

Im Grunde wird es folgendermaßen verwendet:

const [isLoading, setLoading] = useState(true);

Auf diese Weise können Sie die setLoadingÜbergabe eines booleschen Werts aufrufen . Es ist eine coole Art, eine "zustandsbehaftete" Funktionskomponente zu haben.


7

useState()ist ein React Hook. Hooks ermöglichen die Verwendung von Status und Veränderlichkeit innerhalb von Funktionskomponenten.

Während Sie keine Hooks in Klassen verwenden können, können Sie Ihre Klassenkomponente mit einer Funktion eins umschließen und Hooks daraus verwenden. Dies ist ein großartiges Tool zum Migrieren von Komponenten von der Klasse in die Funktionsform. Hier ist ein vollständiges Beispiel:

In diesem Beispiel werde ich eine Zählerkomponente verwenden. Das ist es:

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: props.count };
  }
  
  inc() {
    this.setState(prev => ({count: prev.count+1}));
  }
  
  render() {
    return <button onClick={() => this.inc()}>{this.state.count}</button>
  }
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>

Es ist eine einfache Klassenkomponente mit einem Zählstatus, und die Statusaktualisierung erfolgt über Methoden. Dies ist ein sehr häufiges Muster in Klassenkomponenten. Das erste ist, es mit einer Funktionskomponente mit demselben Namen zu umschließen, die alle ihre Eigenschaften an die umschlossene Komponente delegiert. Außerdem müssen Sie die umschlossene Komponente in der Funktionsrückgabe rendern. Hier ist es:

function Hello(props) {
  class Hello extends React.Component {
    constructor(props) {
      super(props);
      this.state = { count: props.count };
    }

    inc() {
      this.setState(prev => ({count: prev.count+1}));
    }

    render() {
      return <button onClick={() => this.inc()}>{this.state.count}</button>
    }
  }
  return <Hello {...props}/>
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>

Dies ist genau dieselbe Komponente mit demselben Verhalten, demselben Namen und denselben Eigenschaften. Heben wir nun den Zählzustand auf die Funktionskomponente. So läuft es:

function Hello(props) {
  const [count, setCount] = React.useState(0);
  class Hello extends React.Component {
    constructor(props) {
      super(props);
      this.state = { count: props.count };
    }

    inc() {
      this.setState(prev => ({count: prev.count+1}));
    }

    render() {
      return <button onClick={() => setCount(count+1)}>{count}</button>
    }
  }
  return <Hello {...props}/>
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>
<div id='root'></div>

Beachten Sie, dass die Methode incimmer noch vorhanden ist und niemanden verletzt. Tatsächlich handelt es sich um toten Code. Dies ist die Idee, einfach den Zustand weiter anzuheben. Wenn Sie fertig sind, können Sie die Klassenkomponente entfernen:

function Hello(props) {
  const [count, setCount] = React.useState(0);

  return <button onClick={() => setCount(count+1)}>{count}</button>;
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>

<div id='root'></div>

Dies ermöglicht zwar die Verwendung von Hooks in Klassenkomponenten, ich würde Ihnen dies jedoch nicht empfehlen, es sei denn, Sie migrieren wie in diesem Beispiel. Das Mischen von Funktions- und Klassenkomponenten macht die Zustandsverwaltung zu einem Chaos. ich hoffe das hilft

Freundliche Grüße


7

useState () ist ein integrierter Beispiel-React-Hook, mit dem Sie Zustände in Ihren Funktionskomponenten verwenden können. Dies war vor Reaktion 16.7 nicht möglich.

Die useState-Funktion ist ein integrierter Hook, der aus dem Reaktionspaket importiert werden kann. Sie können Ihren Funktionskomponenten den Status hinzufügen. Mit dem useState-Hook in einer Funktionskomponente können Sie einen Status erstellen, ohne zu Klassenkomponenten zu wechseln.


5

Haken sind eine neue Funktion in React v16.7.0-alpha useStateder "Haken". useState()Legen Sie den Standardwert einer beliebigen Variablen fest und verwalten Sie diese in der Funktionskomponente (PureComponent-Funktionen). ex : const [count, setCount] = useState(0);Setzen Sie den Standardwert von count 0. und u kann setCountto incrementoder decrementden Wert verwenden. onClick={() => setCount(count + 1)}Erhöhen Sie den Zählwert. DOC


4

Danke Loelsonk, ich habe es getan

const [dataAction, setDataAction] = useState({name: '', description: ''});

    const _handleChangeName = (data) => {
        if(data.name)
            setDataAction( prevState  => ({ ...prevState,   name : data.name }));
        if(data.description)
            setDataAction( prevState  => ({ ...prevState,   description : data.description }));
    };
    
    ....return (
    
          <input onChange={(event) => _handleChangeName({name: event.target.value})}/>
          <input onChange={(event) => _handleChangeName({description: event.target.value})}/>
    )


2

useState ist ein Hook, mit dem Sie einer Funktionskomponente den Status hinzufügen können. Es akzeptiert ein Argument, das der Anfangswert der State-Eigenschaft ist, und gibt den aktuellen Wert der State-Eigenschaft sowie eine Methode zurück, mit der diese State-Eigenschaft aktualisiert werden kann.
Das Folgende ist ein einfaches Beispiel:
import React, {useState} from react
function HookCounter {
const [count, stateCount]= useState(0)
return(
<div>
<button onClick{( ) => setCount(count+1)}> count{count} </button>
</div>
)
}

useState akzeptiert den Anfangswert der Statusvariablen, der in diesem Fall Null ist, und gibt ein Wertepaar zurück. Der aktuelle Wert des Status wurde als count bezeichnet, und eine Methode zum Aktualisieren der Statusvariablen wurde als setCount aufgerufen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.