Deep Dive into React Hooks Part #2: useState Hook

React Hooks

I hope you have a better understanding of React Hooks basics. If you are not familiar with why and what about React Hooks and Basics, I highly recommend you to read the first article on this article series and follow onwards to deeply understand everything about React Hooks and it’s usage.

Syntax and Usage

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

As the Official document explained, a hook is a unique kind of function that allows us to “hook into” React features.

If we look at the above useState hook syntax, you can see that it returns a pair of values representing the current state and a function that lets us update the state respectively.

useState FAQ

What does happen when calling the useState ?

When we call the useState, it declares a “state variable” by the name we specify. In the above example, we have called it as ‘state’ but we can have any name we want. (i.e apple, banana, or anything.). Also for the function that’s return by the useState can have any name you want(i.e setAppleCoune etc.)

const [ banana, setBananaList ] = useState(initialState);

If you are coming from a JavaScript background as you know once you call and finish executing a function all the values associated with that function also get “disappear” after the execution. But with hooks React makes sure that this state variable value is preserved even after a rerender (i.e multiple function calls).

What do we pass to useState ?

It accepts one single argument and it can have any value you want. Such as a boolean, int, array, null, undefined, etc, or even an object.

const initialState = [];
const [bananaList, setBananaList] = useState(initialState);

What does useState return?

It returns a pair of values: the current state and a function that updates it. This syntax maybe looks odd to you at first glance if you haven’t used them before. It’s called “array destructuring”.

What happens in the initial render :

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

const initialState = [];
const [bananaList, setBananaList] = useState(initialState);
console.log(bananaList); // Output --> []

What happens if we called the setState function after initial the render:

setBananaList([{id: 1, bananaName:'Red Banana'}]);
console.log(bananaList);// Output [{id: 1, bananaName:'Red Banana'}]

It will update the state value to a new value and then enqueues a re-render of the component.

If it’s called after the initial render, the first value returned will be the most recent after the executed updates.

Usage of useState Hook

Hope you have a basic understanding about use state hook, now let’s look at a couple of example of using useState hook in applications. You can use this useState hook in different ways as follows:

Using a single state variable:

const Counter = ({ initialCount = 0 }) => {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>
Reset
</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>
-
</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>
+
</button>
</>
);
}

Using multiple state variables:

const UserInput = () => {
const [age, setAge] = useState('');
const [name, setName] = useState('');

return (
<div>
<input
type="number"
value={age}
placeholder="Enter age"
onChange={e => setAge(e.target.value)}
/>
<p>
<strong>My Age : {age}</strong>
</p>
<input
type="text"
value={name}
placeholder="Enter name"
onChange={e => setName(e.target.value)}
/>
<p>
<strong>My Name : {name}</strong>
</p>
</div>
);
};

Using multiple variables in a one state variable:

const UserInput = () => {
const [state, setState] = useState({ name: '', age: '' });
const { name, age } = state;
return (
<div>
<input
type="number"
value={age}
placeholder="Enter age"
onChange={e => setState({ ...state, age: e.target.value })}
/>
<p>
<strong>My Age : {age}</strong>
</p>
<input
type="text"
value={name}
placeholder="Enter name"
onChange={e => setState({...state, name: e.target.value})}
/>
<p>
<strong>My Name : {age}</strong>
</p>
</div>
);
};

Lazy initial state

Other notable thing regarding useState hook is that, initialState that we pass to the hook will only be used in the initial render to initialize the initial state of the value. In the following renders of the component, that initialState value will be disregarded. If the initial state is the result of an expensive computation, it will be ideal to provide as a function as follows, which will be executed only on the initial render.

const [state, setState] = useState(() => {
const initialState = expensiveComputationForInitialState(props);
return initialState;
});

I hope covered all most all the concepts and gotcha related to useState hook. If you have questions related to this, you ask them in the comment section.

Versatile Full-stack Developer with 5+ years of experience designing, developing, and managing complex applications and internal frameworks.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store