[REACT](https://www.kirupa.com/react/index.htm)
[BOOK](https://www.amazon.com/exec/obidos/ASIN/0134546318/kirupacom)
# Dealing With State in React
by [ kirupa](https://www.kirupa.com/me/index.htm) | filed under [Learning React](https://www.kirupa.com/react/index.htm)
Up until this point, the components we've created have been stateless. They have properties (aka props) that are passed in from their parent, but nothing changes about them once the components come alive. Your properties are considered immutable once they have been set. For many interactive scenarios, you don't want that. You want to be able to change aspects of your components as a result of some user interaction (or some data getting returned from a server or a billion other things!)
What we need is another way to store data on a component that goes beyond properties. We need a way to store data that can be changed. What we need is something known as **state**! In this tutorial we are going to learn all about it and how you can use it to create stateful components.
Onwards!
## Using States
If you know how to work with properties, you totally know how to work with states...sort of. There are some differences, but they are too subtle to bore you with right now. Instead, let's just jump right in and see states in action by using them in a small example.
What we are going to is create a simple lightning counter example:

What this example does is nothing crazy. Lightning strikes the earth's surface about [100 times a second](http://environment.nationalgeographic.com/environment/natural-disasters/lightning-profile/). We have a counter that simply increments a number you see by that same amount. Let's create it.
### Our Starting Point
The primary focus of this example is to see how we can work with state. There is no point in us spending a bunch of time creating the example from scratch and retracing paths that we've walked many times already. That's not the best use of anybody's time.
Instead of starting from scratch, modify an existing HTML document or create a new one with the following contents:
```js
Dealing with State
```
The bulk of this component is the `divStyle` object that contains the styling information responsible for the cool rounded background. The `return` function returns a `div` element that wraps the `LightningCounter` component.
The `LightningCounter` component is where all the action is going to be taking place:
```js
class LightningCounter extends React.Component {
render() {
return (
Hello!
);
}
}
```
This component, as it is right now, has nothing interesting going for it. It just returns the word **Hello!** That's OK - we'll fix this component up later.
The last thing to look at is our `ReactDOM.render` method:
```js
ReactDOM.render(
,
document.querySelector("#container")
);
```
It just pushes the `LightningCounterDisplay` component to our **container** element in our DOM. That's pretty much it. The end result is you see the combination of markup from our `ReactDOM.render` method and the `LightningCounterDisplay` and `LightningCounter` components.
## Getting Our Counter On
Now that we have an idea of what we are starting with, it's time to make plans for our next steps. The way our counter works is pretty simple. We are going to be using a `setInterval` function that calls some code every 1000 milliseconds (aka 1 second). That "some code" is going to increment a value by **100** each time it is called. Seems pretty straightforward, right?
To make this all work, we are going to be relying on three APIs that our React Component exposes:
1. `componentDidMount`
1. `setState`
We'll see these APIs in use shortly, but I wanted to give you a preview of them so that you can spot them easily in a lineup!
### Setting the Initial State Value
We need a variable to act as our counter, and let's call this variable `strikes`. There are a bunch of ways to create this variable. The most obvious one is the following:
```js
var strikes = 0; // :P
```
We don't want to do that, though. For our example, the `strikes` variable is part of our component's state. The way to do this is by creating a state object, making our `strikes` variable be a property of it, and ensure we set all of this up when our component is getting created. The component we want to do all of this to is `LightningCounter`, so go ahead and add the following highlighted lines:
```js
class LightningCounter extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
strikes: 0
};
}
render() {
return (
Hello!
);
}
}
```
We specify our `state` object inside our `LightningCounter` component's constructor. This runs waaaay before your component gets rendered, and what we are doing is telling React to set an object containing our `strikes` property (initialized to **0**).
If we inspect the value of our `state` object after this code has run, it would look something like the following:
```js
var state = {
strikes: 0
};
```
Before we wrap this section up, let's visualize our `strikes` property. In our `render` method, make the following highlighted change:
```js
class LightningCounter extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
strikes: 0
};
}
render() {
return (
{this.state.strikes}
);
}
}
```
What we've done is replaced our default **Hello!** text with an expression that displays the value stored by the `this.state.strikes` property. If you preview your example in the browser, you will see a value of **0** displayed. That's a start!
### Starting Our Timer & Setting State
Next up is getting our timer going and incrementing our `strikes` property. Like we mentioned earlier, we will be using the `setInterval` function to increase the `strikes` property by **100** every second. We are going to do all of this immediately after our component has been rendered using the built-in `componentDidMount` method.
The code for kicking off our timer looks as follows:
```js
class LightningCounter extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
strikes: 0
};
}
componentDidMount() {
setInterval(this.timerTick, 1000);
}
render() {
return (
{this.state.strikes}
);
}
}
```
Go ahead and add these highlighted lines to our example. Inside our `componentDidMount` method that gets called once our component gets rendered, we have our `setInterval` method that calls a `timerTick` function every second (or 1000 milliseconds).
We haven't defined our `timerTick` function, so let's fix that by adding the following highlighted lines to our code:
```js
class LightningCounter extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
strikes: 0
};
}
timerTick() {
this.setState({
strikes: this.state.strikes + 100
});
}
componentDidMount() {
setInterval(this.timerTick, 1000);
}
render() {
return (
{this.state.strikes}
);
}
}
```
What our `timerTick` function does is pretty simple. It just calls `setState`. The `setState` method comes in various flavors, but for what we are doing here, it just takes an object as its argument. This object contains all the properties you want to **merge into the `state` object.** In our case, we are specifying the `strikes` property and setting its value to be 100 more than what it is currently.
#### Note: Incrementing the Existing State Value
Just like you've seen here, you will often end up modifying an existing state value with an updated value. The way we are getting the existing state value is by calling `this.state.strikes`. For performance-related reasons, React may decide to batch state updates in rapid succession. This could lead to the original value stored by `this.state` to be out-of-sync with reality. To help with this, the `setState` method gives you access to the previous state object via the `prevState` argument.
By using that argument, our code could be made to look as follows:
```js
this.setState((prevState) => {
return {
strikes: prevState.strikes + 100
};
});
```
The end result is similar to what we had originally. Our `strikes` property is incremented by 100. The only potential change is that the value of the `strikes` property is guaranteed to be whatever the earlier value stored by our `state` object would be.
So, should you use this approach for updating your state? There are good arguments on both sides. One side argues for correctness, despite the original approach of using `this.state` working out fine for most real-world cases. The other side argues for keeping the code simple and not introducing additional complexity. There is no right or wrong answer here. Use whatever approach you prefer. I'm only calling this out for completeness, for you may run into the `prevState` approach in any React code you encounter in the wild.
There is one more thing you need to do. The `timerTick` function has been added to our component, but ***its contents*** aren't scoped to our component. In other words, the `this` keyword where we are accessing `setState` will return a `TypeError` in the current situation. There are several solutions you can employ here - each a little frustrating in its own way. We'll look at this problem in detail later, but for now, we are going to explicitly bind our timerTick function to our component so that all of the `this` references resolve properly. Add the following line to our constructor:
```js
constructor(props, context) {
super(props, context);
this.state = {
strikes: 0
};
this.timerTick = this.timerTick.bind(this);
}
```
Once you've done this, our `timerTick` function is ready to be a useful part of our component!
### Rendering the State Change
If you preview your app now, you'll see our `strikes` value start to increment by 100 every second:

Let's ignore for a moment what happens with our code. That is pretty straightforward. The interesting thing is how everything we've done ends up updating what you see on the screen. That updating has to do with this React behavior: **Whenever you call `setState` and update something in the `state` object, your component's `render` method gets automatically called**. This kicks of a cascade of render calls for any component whose output is also affected. The end result of all this is that what you see in your screen in the latest representation of your app's UI state. Keeping your data and UI in sync is one of the hardest problems with UI development, so it's nice that React takes care of this for us. It makes all of this pain of learning to use React totally worth it...almost! :P
## Optional: The Full Code
What we have right now is just a counter that increments by 100 every second. Nothing about it screams ***Lightning Counter***, but it does cover everything about states that I wanted you to learn right now. If you want to optionally flesh out your example to look like my version that you saw at the beginning, below is the full code for what goes inside our `script` tag:
```js
class LightningCounter extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
strikes: 0
};
this.timerTick = this.timerTick.bind(this);
}
timerTick() {
this.setState({
strikes: this.state.strikes + 100
});
}
componentDidMount() {
setInterval(this.timerTick, 1000);
}
render() {
var counterStyle = {
color: "#66FFFF",
fontSize: 50
};
var count = this.state.strikes.toLocaleString();
return (
{count}
);
}
}
class LightningCounterDisplay extends React.Component {
render() {
var commonStyle = {
margin: 0,
padding: 0
};
var divStyle = {
width: 250,
textAlign: "center",
backgroundColor: "#020202",
padding: 40,
fontFamily: "sans-serif",
color: "#999999",
borderRadius: 10
};
var textStyles = {
emphasis: {
fontSize: 38,
...commonStyle
},
smallEmphasis: {
...commonStyle
},
small: {
fontSize: 17,
opacity: 0.5,
...commonStyle
}
};
return (
LIGHTNING STRIKES
WORLDWIDE
(since you loaded this example)
);
}
}
ReactDOM.render(
,
document.querySelector("#container")
);
```
If you make your code look like everything you see above and run the example again, you will see our lightning counter example in all its cyan-colored glory. While you are at it, take a moment to look through the code to ensure you don't see too many surprises.
## Conclusion
We just scratched the surface on what we can do to create stateful components. While using a timer to update something in our state object is cool, the real action happens when we start combining user interaction with state. So far, we've shied away from the large amount of mouse, touch, keyboard, and other related things that your components will come into contact with. We'll fix that up in the future. Along the way, you'll see us taking what we've seen about states to a whole new level! If that doesn't excite you, then I don't know what will :P
**Next tutorial:** [Going from Data to UI](https://www.kirupa.com/react/from_data_to_ui_in_react.htm)