Czym jest useState () w Reaccie?

Obecnie uczę się koncepcji hooków w Reaccie i staram się zrozumieć poniższy przykład.

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

Powyższy przykład zwiększa licznik w parametrze funkcji obsługi. Co jeśli chcę zmodyfikować wartość count wewnątrz funkcji obsługi zdarzeń

Rozważ poniższy przykład:

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>
Author: iliketocode, 2018-11-06

12 answers

Hooki Reacta są nowym sposobem (wciąż rozwijanym) dostępu do podstawowych funkcji Reacta, takich jak state bez konieczności używania klas, w twoim przykładzie jeśli chcesz zwiększyć licznik bezpośrednio w funkcji obsługi bez podawania go bezpośrednio wonClick Propp, możesz zrobić coś w stylu:

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

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

I onClick:

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

Szybko wyjaśnijmy, co dzieje się w tej linii:

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

useState(0) zwraca krotkę, w której pierwsza parametr {[6] } jest bieżącym stanem licznika i {[7] } jest metodą, która pozwoli nam zaktualizować stan licznika. Możemy użyć metody setCounter, aby zaktualizować stan count w dowolnym miejscu - w tym przypadku używamy jej wewnątrz funkcji setCount, gdzie możemy zrobić więcej rzeczy; idea hooków polega na tym, że jesteśmy w stanie utrzymać nasz kod bardziej funkcjonalny i unikać komponentów opartych na klasach, jeśli nie jest to pożądane/potrzebne.

Napisałem cały artykuł o hookach z wieloma przykłady (w tym liczniki) takie jak ten kod , wykorzystałemuseState, useEffect, useContext, i własne haki . Mógłbym uzyskać więcej informacji o tym, jak Hooki działają na tę odpowiedź, ale dokumentacja bardzo dobrze wyjaśnia hook state i inne Hooki w szczegółach, mam nadzieję, że to pomoże.

Aktualizacja: Hooki nie są już propozycją , ponieważ wersja 16.8 są teraz dostępne do użytku, jest sekcja w Strona Reacta, która odpowiada na niektóre z FAQ.

 190
Author: Enmanuel Duran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-19 15:39:57

useState jest jednym z wbudowanych hooków reactowych dostępnych w wersji 0.16.7.

useState powinien być stosowany tylko wewnątrz elementów funkcjonalnych. {[7] } jest sposobem, jeśli potrzebujemy stanu wewnętrznego i nie musimy implementować bardziej złożonej logiki, takiej jak metody cyklu życia.

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

Zwraca wartość stanu i funkcję do jej aktualizacji.

Podczas początkowego renderowania zwracany stan (state) jest taki sam jak wartość przekazywana jako pierwszy argument (initialState).

Funkcja setState jest używana do aktualizacji stanu. Przyjmuje nowy state value i pyta o ponowne renderowanie komponentu.

Należy pamiętać , że useState wywołanie wywołania hook dla aktualizacji stanu zachowuje się inaczej niż komponenty this.setState. Aby pokazać różnicę, przygotowałem dwa przykłady.

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/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

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

Nowy obiekt jest tworzony przy użyciu wywołania zwrotnego setUserInfo. Zauważ, że straciliśmy lastName wartość klucza. Aby naprawić, że możemy przejść funkcja wewnątrz useState.

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

Zobacz przykład:

// 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/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

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

W przeciwieństwie do metody setState znalezionej w komponentach klasy, useState robi nie łączy automatycznie obiektów aktualizacji. Możesz to powtórzyć zachowanie poprzez połączenie funkcji Updater form z object spread składnia:

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

Aby dowiedzieć się więcej o useState Zobacz oficjalna dokumentacja .

 63
Author: loelsonk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-02 21:02:51

Składnia useState hook jest prosta.

const [value, setValue] = useState(defaultValue)

Jeśli nie znasz tej składni, przejdź tutaj.

Polecam lekturę dokumentacji .Istnieją doskonałe wyjaśnienia z przyzwoitą ilością przykładów.

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>
   );
 }
 19
Author: Jan Ciołek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-23 13:09:07

useState() jest hakiem Reactowym. Hooki umożliwiają wykorzystanie stanu i zmienności wewnątrz komponentów funkcji.

Podczas gdy nie możesz używać hooków wewnątrz klas, możesz zawinąć komponent klasy za pomocą funkcji 1 i użyć hooków z niego. Jest to świetne narzędzie do migracji komponentów z klasy do formy funkcji. Oto pełny przykład:

W tym przykładzie użyję komponentu licznika. To jest to:

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>

Jest to prosty komponent klasy ze stanem licznika, a Aktualizacja stanu odbywa się metodami. Jest to bardzo powszechny wzorzec w komponentach klasy. Pierwszą rzeczą jest zawinięcie go komponentem funkcyjnym o tej samej nazwie, który deleguje wszystkie jego właściwości do zawiniętego komponentu. Ponadto musisz renderować zawinięty komponent w funkcji return. Oto ona:

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>

Jest to dokładnie ten sam komponent, o tym samym zachowaniu, tej samej nazwie i tych samych właściwościach. Teraz podnosimy liczenie stan komponentu funkcyjnego. Tak to jest:

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>

Zauważ, że metoda inc nadal istnieje, nie zaszkodzi nikomu, w rzeczywistości jest martwym kodem. To jest pomysł, po prostu podnoś stan w górę. Po zakończeniu możesz usunąć komponent klasy:

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>

Chociaż pozwala to na użycie hooków wewnątrz komponentów klasy, nie polecam ci tego robić, chyba że migraujesz tak, jak to zrobiłem w tym przykładzie. Miksowanie komponenty funkcji i klasy sprawią, że zarządzanie stanem stanie się bałaganem. Mam nadzieję, że to pomoże

Pozdrawiam

 9
Author: geckos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-06 00:25:39

useState jest jednym z hooków dostępnych w Reaccie v16. 8. 0. To zasadniczo pozwala włączyć swoje inne niestateczne/funkcjonalne komponenty do takich, które mogą mieć swój własny stan.

Na bardzo podstawowym poziomie, jest używany w ten sposób:

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

To pozwala wywołać setLoading przekazując wartość logiczną. To fajny sposób na posiadanie" stateful " functional component.

 8
Author: codejockie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-01 00:55:05

UseState() jest przykładowym wbudowanym Hookiem Reactowym, który pozwala używać stanów w komponentach funkcjonalnych. Nie było to możliwe przed reactem 16.7.

Funkcja useState jest wbudowanym Hookiem, który można zaimportować z pakietu reactowego. Pozwala na dodanie stanu do komponentów funkcjonalnych. Używając Hooka useState wewnątrz komponentu funkcyjnego, można utworzyć fragment stanu bez przełączania na komponenty klasy.

 7
Author: Muhammad Shaheem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-19 07:17:09

Hooki to nowa funkcja w React v16.7.0-alpha useState to "hak". useState() Ustaw domyślną wartość zmiennej any i zarządzaj w komponencie funkcyjnym (funkcje PureComponent). ex : const [count, setCount] = useState(0); Ustaw domyślną wartość count 0. i można użyć setCount do increment lub decrement wartości. onClick={() => setCount(count + 1)} zwiększ wartość zliczania.DOC

 5
Author: Asif vora,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-08 13:08:49

Dzięki loelsonk, zrobiłem tak

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})}/>
    )
 5
Author: Yanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-17 10:43:44

UseState jest Hookiem, który pozwala dodać stan do komponentu funkcjonalnego. Przyjmuje argument, który jest wartością początkową właściwości state i zwraca bieżącą wartość state property oraz metodę, która jest w stanie aktualizować tę własność state.
Poniżej znajduje się prosty przykład:

import React, {useState} from react    

function HookCounter {    
  const [count, stateCount]= useState(0)    
    return(    
      <div>     
        <button onClick{( ) => setCount(count+1)}> count{count}</button>    
      </div>    
    )   
 }

UseState przyjmuje wartość początkową zmiennej stanu, która w tym przypadku jest równa zero i zwraca parę wartości. Bieżąca wartość stanu została wywołana count i metoda, która can update zmienna stanowa została wywołana jako setCount.

 2
Author: Abhishek Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-06 04:26:50

Zasadniczo React.useState(0) magicznie widzi, że powinien zwrócić krotkę count i setCount (metoda zmiany count). Parametr useState przyjmuje wartość początkową count.

  const [count, setCount] = React.useState(0);
  const [count2, setCount2] = React.useState(0);

  // increments count by 1 when first button clicked
  function handleClick(){
    setCount(count + 1);
  } 

  // increments count2 by 1 when second button clicked
  function handleClick2(){
    setCount2(count2 + 1);
  } 

  return (
    <div>
      <h2>A React counter made with the useState Hook!</h2>
      <p>You clicked {count} times</p>
      <p>You clicked {count2} times</p>
      <button onClick={handleClick}>
        Click me
      </button> 
      <button onClick={handleClick2}>
        Click me2
      </button>
  );

Bazuje na przykładzie Enmanuela Durana, ale pokazuje dwa liczniki i zapisuje funkcje lambda jako normalne funkcje, więc niektórzy mogą to łatwiej zrozumieć.

 1
Author: Philip Rego,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-20 06:36:02

Odpowiedzi podane powyżej są dobre, ale pozwól mi po prostu chip, {[1] } jest asynchroniczna, więc jeśli następny stan jest zależny od poprzedniego stanu, najlepiej przekazać useState callback. Zobacz przykład poniżej:

import { useState } from 'react';

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

  return (
    <div>
      <p>You clicked {count} times</p>
      // passing a callback to useState to update count
      <button onClick={() => setCount(count => count + 1)}>
        Click me
      </button>
    </div>
  );
}

Jest to zalecany sposób, jeśli nowy stan zależy od obliczeń ze starego stanu.

 1
Author: Lawrence Eagles,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-28 14:55:54

UseState jest Hookiem, który pozwala na posiadanie zmiennych stanu w komponentach funkcyjnych.

W Reaccie są dwa rodzaje komponentów: class i functional components.

Komponenty klas są klasami ES6, które rozciągają się od Reacta.Komponent i może mieć metody stanu i cyklu życia:

class Message extends React.Component {
constructor(props) {
super(props);
this.state = {
  message: ‘’    
 };
}

componentDidMount() {
/* ... */
 }

render() {
return <div>{this.state.message}</div>;
  }
}

Komponenty funkcyjne są funkcjami, które po prostu przyjmują argumenty jako właściwości komponentu i zwracają poprawne JSX:

function Message(props) {
  return <div>{props.message}</div>
 }
// Or as an arrow function
const Message = (props) =>  <div>{props.message}</div>

Jak widzisz, nie ma stanu ani cyklu życia metody.

 1
Author: Saad Bilal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-08 10:16:29