What is useState() in React?
Asked Answered
D

14

232

I am currently learning hooks concept in React and trying to understand below example.

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

The above example increments the counter on the handler function parameter itself. What if I want to modify count value inside event handler function

Consider below example:

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>
Diaphaneity answered 6/11, 2018 at 4:56 Comment(1)
You can also look in the source code to understand how useState is implemented. Here is the definition as of version 16.9.Lingam
H
245

React hooks are a new way (still being developed) to access the core features of react such as state without having to use classes, in your example if you want to increment a counter directly in the handler function without specifying it directly in the onClick prop, you could do something like:

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

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

and onClick:

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

Let's quickly explain what is going on in this line:

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

useState(0) returns a tuple where the first parameter count is the current state of the counter and setCounter is the method that will allow us to update the counter's state. We can use the setCounter method to update the state of count anywhere - In this case we are using it inside of the setCount function where we can do more things; the idea with hooks is that we are able to keep our code more functional and avoid class based components if not desired/needed.

I wrote a complete article about hooks with multiple examples (including counters) such as this codepen, I made use of useState, useEffect, useContext, and custom hooks. I could get into more details about how hooks work on this answer but the documentation does a very good job explaining the state hook and other hooks in detail.

update: Hooks are not longer a proposal, since version 16.8 they're now available to be used, there is a section in React's site that answers some of the FAQ.

Hairtail answered 6/11, 2018 at 5:26 Comment(6)
Good analogy except that JavaScript doesn't technically have a tuple data typeGelding
Well, the destructured assignment is used like tuple https://mcmap.net/q/119813/-javascript-variable-assignments-from-tuplesOctastyle
Are hooks async? When using setSomething , if I then try use something directly afterwards, it seems to have the old value still...Nerissanerita
Hooks do not update it's value after 'set value' call until a component is rerendered. Supercharged useState by Hookstate (hookstate.js.org) library gives you immediate value update and whole lot more features. Disclaier: I am an author of the lib.Corticate
Can you also address why we associate const to a state that will definitelly change? const count looks weird to meGreenebaum
@Gelding a tuple is a finite ordered list (sequence) of elementsRiding
M
78

useState is one of build-in react hooks available in 0.16.7 version.

useState should be used only inside functional components. useState is the way if we need an internal state and don't need to implement more complex logic such as lifecycle methods.

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

Returns a stateful value, and a function to update it.

During the initial render, the returned state (state) is the same as the value passed as the first argument (initialState).

The setState function is used to update the state. It accepts a new state value and enqueues a re-render of the component.

Please note that useState hook callback for updating the state behaves differently than components this.setState. To show you the difference I prepared two examples.

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>

New object is created when setUserInfo callback is used. Notice we lost lastName key value. To fixed that we could pass function inside useState.

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

See example:

// 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>

Unlike the setState method found in class components, useState does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax:

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

For more about useState see official documentation.

Meridethmeridian answered 2/12, 2018 at 21:2 Comment(2)
Thanks for adding a function as parameter in the example.Bywaters
your comparative examples helped a newbie like to me understand the use of useStateSmirch
B
25

The syntax of useState hook is straightforward.

const [value, setValue] = useState(defaultValue)

If you are not familiar with this syntax, go here.

I would recommend you reading the documentation.There are excellent explanations with decent amount of examples.

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>
   );
 }
Bertero answered 6/11, 2018 at 5:20 Comment(3)
This should be the accepted answer. Concise and clear, with good external references.Antisyphilitic
This is the worst answer, copy/paste of the doc page basically. I came here because the doc page was confusingWohlert
What confuses you my friend?Its hard to find better explanation than in official documentation.Five
C
12

useState() is a React hook. Hooks make possible to use state and mutability inside function components.

While you can't use hooks inside classes you can wrap your class component with a function one and use hooks from it. This is a great tool for migrating components from class to function form. Here is a complete example:

For this example I will use a counter component. This is it:

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>

It is a simple class component with a count state, and state update is done by methods. This is very common pattern in class components. The first thing is to wrap it with a function component with just the same name, that delegate all its properties to the wrapped component. Also you need to render the wrapped component in the function return. Here it is:

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>

This is exactly the same component, with the same behavior, same name and same properties. Now lets lift the counting state to the function component. This is how it goes:

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>

Note that the method inc is still there, it wont hurt anybody, in fact is dead code. This is the idea, just keep lifting state up. Once you finished you can remove the class component:

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>

While this makes possible to use hooks inside class components, I would not recommend you to do so except if you migrating like I did in this example. Mixing function and class components will make state management a mess. I hope this helps

Best Regards

Chivalrous answered 6/8, 2019 at 0:25 Comment(0)
J
9

useState is one of the hooks available in React v16.8.0. It basically lets you turn your otherwise non-stateful/functional components to one that can have its own state.

At the very basic level, it's used this way:

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

This then lets you call setLoading passing a boolean value. It's a cool way of having "stateful" functional component.

Jameejamel answered 6/11, 2018 at 5:44 Comment(0)
S
8

useState() is an example built-in React hook that lets you use states in your functional components. This was not possible before React 16.7.

The useState function is a built in hook that can be imported from the react package. It allows you to add state to your functional components. Using the useState hook inside a function component, you can create a piece of state without switching to class components.

Septet answered 6/11, 2018 at 6:33 Comment(0)
H
6

Thanks loelsonk, i did so

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})}/>
    )
Hukill answered 17/12, 2019 at 10:43 Comment(0)
Y
5

Hooks are a new feature in React v16.7.0-alpha useState is the “Hook”. useState() set the default value of the any variable and manage in function component(PureComponent functions). ex : const [count, setCount] = useState(0); set the default value of count 0. and u can use setCount to increment or decrement the value. onClick={() => setCount(count + 1)} increment the count value.DOC

Yusem answered 6/11, 2018 at 5:9 Comment(0)
S
3

useState is a hook that lets you add state to a functional component. It accepts an argument which is the initial value of the state property and returns the current value of state property and a method which is capable of updating that state property.
Following is a simple example:

import React, { useState } from react    

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

useState accepts the initial value of the state variable which is zero in this case and returns a pair of values. The current value of the state has been called count and a method that can update the state variable has been called as setCount.

Swung answered 16/5, 2020 at 18:35 Comment(0)
M
3

React useState is the React Hook that allows you to manage the state within functional components.

For example:

import React, { useState } from 'react'

const Example = () => {
  // create the "counter" state
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>Button clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Count + 1
      </button>
    </div>
  )
}

export default Example

With useState you can easily create stateful functional components. The old equivalent way, using class components with Component class and setState is:

import React, { Component } from 'react'

class Example extends Component {
  constructor(props) {
    super(props)
    this.state = { count: 0 }
  }

  render() {
    const { count } = this.state
    return (
      <div>
        <p>Button clicked {count} times</p>
        <button onClick={() => this.setState({ count: count + 1 })}>
          Count + 1
        </button>
      </div>
    )
  }
}

export default Example

Source:

Links:

Midi answered 2/4, 2021 at 16:54 Comment(0)
R
3

Lets understand useState very easily in simple manner

suppose we have react code:-

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Test from './components/Test.jsx'
ReactDOM.render(
  <div>
      <Test />
  </div>
,
  document.getElementById('root')
);

Test.jsx

import React from "react";

function Test() {
  var x = 5;
  function update() {
    console.log(x);
    return x++;
  }
  return (
    <div>
      <h1>{x}</h1>
      <button onClick={update}>click</button>
    </div>
  );
}
export default Test;

here,the page will show 5 , although we invoke update function by clicking button because we update x but not at between h1 tag , but in real, x is continiously change whenever we click on but it can saw on console

see result and check console by clicking this link

here usState works magically ,

Test.jsx with using useState

import React, { useState } from "react";

function Test() {
  var x = 5;
  const [value, setValue] = useState(x);

  function update() {
    setValue(value + 1);
  }

  return (
    <div>
      <h1>{value}</h1>
      <button onClick={update}>click</button>
    </div>
  );
}
export default Test;

see result by clicking this link

here, by clicking button the value will continiously update, because here we use useState ,it is a function which return 2 things one is current state value and another one is function , if we pass any value to this function it will update current state vlue and current state value update its value in all places wherever it used without writing any extra code.

Riddle answered 21/7, 2021 at 11:9 Comment(0)
M
2

Basically React.useState(0) magically sees that it should return the tuple count and setCount (a method to change count). The parameter useState takes sets the initial value of 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>
  );

Based off Enmanuel Duran's example, but shows two counters and writes lambda functions as normal functions, so some people might understand it easier.

Magness answered 20/9, 2020 at 6:36 Comment(0)
A
1

The answers provided above are good but let me just chip in, useState is async so if your next state is dependent on your previous state it is best you pass useState a callback. See the example below:

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

This is the recommended way if your new state depends on computation from the old state.

Adao answered 28/9, 2020 at 14:55 Comment(0)
E
0

useState is a Hook that allows you to have state variables in functional components.

There are two types of components in React: class and functional components.

Class components are ES6 classes that extend from React.Component and can have state and lifecycle methods:

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

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

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

Functional components are functions that just accept arguments as the properties of the component and return valid JSX:

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

As you can see, there are no state or lifecycle methods.

Evoke answered 8/12, 2020 at 10:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.