useState

The signature for the useState Hook is as follows:

Here, state and setState refer to the state value and updater function returned on invoking useState with some initialState.

It’s important to note that when your component first renders and invokes useState, the initialState is the returned state from useState.

Declare State Variable

Update State Variable

Also, to update state, the state updater function setState should be invoked with a new state value, as shown below:

By doing this, a new re-render of the component is queued. useState guarantees that the state value will always be the most recent after applying updates.

For referential checks, the setState function’s reference never changes during re-renders.

If you try to update state with the same value as the current state, React won’t render the component children or fire effects, e.g., useEffect callbacks. React compares previous and current state via the Object.is comparison algorithm; if they are equal, it ignores the re-render.

It’s important to note that in some cases, React may still render the specific component whose state was updated. That’s OK because React will not go deeper into the tree, i.e., render the component’s children.

Here an example of a Counter component that use useState to update the counter by one for each click

Functional updates

The state setter function returned by useState can be invoked in two ways. The first is by passing a new value directly as an argument:

This is correct and works perfectly in most cases. However, there are cases where a different form of state update is preferred: functional updates.

Here’s the example above revised to use the functional update form:

You pass a function argument to setState. Internally, React will invoke this function with the previous state as an argument. Whatever is returned from this function is set as the new state.

When your new state depends on the previous state value β€” e.g., a computation β€” favor the functional state update. Since setState is async, React guarantees that the previous state value is accurate.

Here’s an example:

In the example above, the button grows every time it’s clicked. Since the new state value depends on the old, the functional update form of setState is preferred.

Lazily initializing state

The initialState argument to useState is only used during your initial render.

Initialize state from function

If the initial state is a result of an expensive computation, you could also pass a function, which will be invoked only on initial render:

As opposed to just passing an initial state value, state could also be initialized from a function, as shown below:

Use with objects

As opposed to strings and numbers, you could also use an object as the initial value passed to useState.

Note that you have to pass the entire object to the useState updater function because the object is replaced, not merged.This is very different from how this.setState worked in classes!

So in order to add an property to the object, we’re using the ES6 spread operator ... to copy the existing properties into the new object,

Pass a function to setState and return a merged object by using the spread operator (Object.assign also works).

Use with arrays

Remember: state can hold any kind of value! Here’s an example of useState holding an array.

Typing into the box and hitting Enter will add an item to the list.

Notice we’re calling useState with an initial value of an empty array [],

Such as objects, in order to add an item to the array, we’re using the ES6 spread operator ... to copy the existing items into the new array, and inserting the new item at the end.

Multiple calls to useState

If you want to store multiple values in a function component, you’ve got a couple options:

  • call useState more than once

  • shove everything into an object

There’s nothing wrong with calling useState multiple times, and in most cases, that’s how I store multiple values. Once you get over 4 or 5 useState calls it gets a bit unwieldy, but if you’re fine with it, React is too.

Multiple state variables may be used and updated from within a functional component as shown below:

If expensive calculations are done within the body of your functional component, i.e., before the return statement, consider optimizing these with useMemo.(we will cover useMemo in another section)

References and articles :

Last updated

Was this helpful?