Now you know how to use state in your React components. Here’s an example:
This code contains an
App component, which renders a child
IncrementButton component. That component tracks a
count variable in its state. It renders a button that lets the user increment the count, and then renders the count itself.
Now, what if you wanted to add a
DecrementButton component that decreased the count whenever it was clicked?
Take a second to think about how you might do that before reading on!
Here are some options you might have thought about:
IncrementButton component and using it in another component. Technically there are ways to do this, but it works against “the philosophy of React” which assumes that a component’s state is private.
If you have multiple components that affect the same state, you should lift the state by following these steps:
That might sound a little confusing, but it looks like this:
Now, the state is tracked in the parent component. The
IncrementButton child component takes in properties for the current count, and for a callback function which it then passes to its button as the
Now the state has been lifted to a parent component, and you’ve seen how to pass callback functions to child components. Now we can get back to adding a
This code now has a parent component that tracks a
count variable in its state, and two child components that modify the state using callback functions.
Note: This example is meant to showcase the concept of lifting state, so I’ve made some design decisions here that I might not make in a “real” codebase. Specifically, in this example you don’t get much from the buttons being their own components, but these concepts become more useful with more complicated codebases. Check out the to-do list section below for an example!
In other words, parent components shouldn’t get any data from a child component’s state. Instead, the parent should track the state, and children should call event callbacks to tell the parent to update the state. The parent should then pass the state down to children as properties.
I personally find this philosophy a little hard to think about, but React makes a little more sense when you start “thinking in React”.
All of this leads to what I think of as React’s state feedback loop. By that I mean, the logic of React apps are structured like this:
For example, let’s modify the above example so that the count stays between
Now the parent component tracks the count, and also passes down a
disabled property that disables each button if the count is about to go out of range. The state flows from the parent, to the children as properties, and back up to the parent as callback functions.
Here’s an updated version of the to-do list example that lifts the state so that the items are listed according to status: