Introduction

State management is a critical part of any React application, and the useState hook is a powerful tool for managing state in React. In this post, we will discuss the basics of useState, as well as how to use it in React with code samples.

What is useState?

The useState hook is a React hook that allows components to manage their own state. It is a function that takes an initial state value and returns an array containing the current state value, along with a function to update it. By utilizing useState, components can independently manage their own state instead of relying on props or a global state management library.

How to Use useState

Declaring state variables

useState is relatively straightforward to use. You simply import the useState hook from React, call the useState function in a component and pass in the initial state value.

import React, { useState } from 'react';

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

In this example, we’ve declared the state variable counter, a function to update the counter state called setCounter, and an initial value of 0.

Reading state variables

To read the current value of a state variable, we can reference it using its name.

import React, { useState } from 'react';

const MyComponent = () => {
	const [counter, setCounter] = useState(0);
	
	return (
		<h1>Counter is set to { counter }</h1>
	);
}

In the above example, we have a <h1> tag, along with the current value of our counter state being rendered inside the tag. Note that we must use the curly braces ({}) when referencing our counter state variable in our component’s return statement as this is technically JSX.

Updating state variables

Updating a state variable is also quite easy! The function to update the state can be called with an argument representing the new state value.

import React, { useState } from 'react';

const MyComponent = () => {
	const [counter, setCounter] = useState(0);

	setCounter(1);
	
	return (
		<h1>Counter is set to { counter }</h1>
	);
}

In the example above, counter is initially set to 0 when declared, and then updated to 1 by calling setCounter with an argument. The final output of the <h1> tag would be “Counter is set to 1”.

Managing Complex State with useState

useState is a great tool for managing simple state values, but it can also be used to manage more complex state values.

Let’s say we have an application that users can log into, and we would like to store the currently logged in user in a state variable. We can achieve this by passing in the currently logged in user to our useState hook.

First, we declare our state variable and set the initial value to null which represents that there is currently no user logged in.

import React, { useState } from 'react';

const MyApp = () => {
	const [user, setUser] = useState(null);
}

Now, when a user logs in we can update our state by calling the setUser function and passing in our user object.

import React, { useState } from 'react';

const MyApp = () => {
	const [user, setUser] = useState(null);

	setUser({
		id: 1,
		firstName: 'Dave',
		lastName: 'Gulati'
	});
}

And just as before, we can now reference our state (user object) in our JSX.

import React, { useState } from 'react';

const MyApp = () => {
	const [user, setUser] = useState(null);

	setUser({
		id: 1,
		firstName: 'Dave',
		lastName: 'Gulati'
	});

	return (
		<h1>Logged in user: { user.firstName }</h1>
	);
}

And just for good measure, we should first check if our user state is null before trying to reference it in our JSX.

import React, { useState } from 'react';

const MyApp = () => {
	const [user, setUser] = useState(null);

	setUser({
		id: 1,
		firstName: 'Dave',
		lastName: 'Gulati'
	});

	return (
		{ user ? 
			<h1>Logged in user: { user.firstName }</h1>
			: <h1>No logged in user</h1>
	);
}

Important note

One thing to keep in mind when using the useState hook is that the function to update the state variable is asynchronous. This means that when you set the state variable, it won’t be updated straight away. This should be fine for most use cases, however, it can occasionally cause some unintended side effects and is something to keep in mind.

Conclusion

In this post we’ve seen how we can use React’s useState hook to manage not only simple state values, but also more complex ones. By utilizing useState, components can independently manage their own state instead of relying on props or a global state management library.