React state is one of the central concepts of the entire React library. Without it, our React components can only become so complex and our apps will never do anything interesting. So in this article, I’m going to guide you through understanding React state from beginning to end, covering both functional and class-based components.
Prerequisite Knowledge
- React Functional Components
- React Class Components
- Basic Rules of JSX
- ES6 destructuring syntax for arrays
Contents
- What is React State?
- How React Components Re-Render
- The React useState Hook
- setState in Class Components
What is React State?
We use the word state to describe the data (variables) used by an application. It’s really that simple. But it’s easiest to understand when you take the word “state” literally. For example, for a typical social media app, the app can be in, or have, the following states:
- A “logged in” state, represented by a Boolean variable such as
isLoggedIn
. - A “feed” state, meaning the current posts feed generated by the app, represented by an array of objects.
- A “dark mode” state (because who doesn’t love dark mode?) represented by a string or a Boolean variable.
Why not just use local variables?
At this point you may be wondering, “What’s the difference between a state variable and a regular variable?” Good question.
There are two main reasons you should not use regular variables for your components’ state:
- Changes to regular variables will not trigger re-renders!
- Regular variables will be reset on every re-render
So what does it mean for a component to “re-render”? Let’s find out.
How React Components Re-Render
Imagine you are making a Counter app in React (I know it’s cliche, just hold on). This means you will have a state variable called count
that tracks how many times the increment button has been clicked. With a local, regular variable, here’s how this might work:
const Counter = () => {
let count = 0;
const handleClick = () => count++;
return (
<div id='counter'>
<h2>{ count }</h2>
<button onClick={handleClick}>Increment</button>
</div>
);
};
Now look at the GIF below, showing what happens when you try to use this Counter app.
If you want the data shown in the UI to be updated when it changes, the component needs to re-render – meaning, to refresh its DOM elements with the new, updated data. Incrementing the count
variable does not trigger a re-render because it’s just a plain, old variable. To update the UI, we need to make count
a state variable.
The React useState Hook
In functional components, we need the useState
hook in order to create a component state. We will learn about React hooks in a later article, but for now you can think of hooks as functions that give us access to cool features, such as React state.
The syntax for using the useState
hook is as follows:
// Don't forget to import it!
import { useState } from 'react';
// Inside a component file...
// Fill in your own identifiers and value for `intialState`
const [state, setState] = useState(initialState);
The useState
hook is called with an initial value, typically the falsy version of whatever data type you need – such as an empty string, the number 0, or just null
. For example, our count
state will start at 0, so that is what we will use as the initial value.
The useState
hook returns an array containing the state variable, and a function you will use to update the state. We can destructure the array using whatever names we like.
Note about the state setter function: We may either pass in the new state value itself, or a callback function that accepts the previous state. You can see both usage types below:
// Initialize the state
const [state, setState] = useState('');
// Passing in a value
setState('Hello World');
// Passing a callback
setState(prev => prev += '!'); // Add an exclamation point
/**********
At this point, the `state` variable contains the string 'Hello World!'
(Notice the exclamation point.)
**********/
Let’s remake that Counter app, using React state and the useState
hook.
import { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
const handleClick = () => setCount(prev => prev + 1);
return (
<div id='counter'>
<h2>{ count }</h2>
<button onClick={handleClick}>Increment</button>
</div>
);
};
Now look at the new GIF. The app is working! Whenever we click the “Increment” button, the count updates!
setState in Class Components
React works a little differently in class components. With class components, we need to add a constructor that initializes the state, and make use of a function called setState
.
Here’s an example of initializing state in a class component:
import React from 'react';
class Component extends React.Component {
constructor(props) {
super(props);
// Fill in your own prop names and values
this.state = {
value1: someValue,
value2: someOtherValue
};
}
}
First, in the constructor, we call the superclass’s constructor function, passing in any props. This is not actually relevant to state, but it is required. We will learn more about this when we get to React props.
Then, to initialize the state, we create a variable called state
that is a property on the class component. This variable will usually be a JavaScript object.
Similar to the setter function for functional component state, we can call setState
with either the new state value or a callback accepting the previous state. You can see both types below:
// Inside the contructor...
this.state = {};
// Later in the file...
setState({
name: 'theLoneCoder',
address: '245 Coder Street'
});
// Adding more properties to the state
setState(prev => ({
...prev,
city: 'CoderVille',
isLonely: true
}));
Now let’s recreate our Counter app with a class component!
import React from 'react';
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
this.handleClick = this.handleClick.bind(this);
}
handleClick = () => this.setState(prev => ({count: prev.count + 1}))
render() {
return (
<div id='counter'>
<h2>{ count }</h2>
<button onClick={this.handleClick}>Increment</button>
</div>
);
}
}
Conclusion
With React state, our React apps have much more potential and more capabilities. In the next article, we’ll learn all about props in React.
One thought on “React State: useState and setState | React Tutorial for Beginners”