setState
and this
One of the great things about React is that it’s just JavaScript. Class components are no exception - they’re just JavaScript classes. This means that they can define a constructor
, and they have access to a this
object — sometimes called the component instance.
Which brings me to the most important thing about class components.
When React encounters an element for a class component, it will instantiate a component instance, and keep it around for the next time that the element needs to be rendered.
Class components can use this
to store information — or state — for subsequent renders.
In contrast, function components only have access to their props
.
Class components can do things that function components can’t. For example, you could keep track of the number of times that a class component has been rendered by incrementing an instance variable.
And there’s one more special thing that class components can do.
setState
methodThe first rule of class components is that they must extend React.Component
. As a result, your classes will inherit a bunch of methods. And the most important inherited method, by far, is setState
.
When you call this.setState(newState)
from a class component, React will schedule a merge of newState
into any existing value of this.state
.
But React will also do something else. See if you can figure out what it is that setState
does by playing with this demo…
Did you figure it out? Once you think you know, or you’re completely stuck, check your answer below.
I mentioned earlier that there are two ways of re-rendering, and now you know the second way!
ReactDOM.render()
As you’ve probably figured out, this is pretty darn important. We’ll discuss why in a moment. But first, I must give you the fine print.
Using setState
from event handlers is simple. But when using it in other contexts, there are some things you’ll need to watch out for.
Calling this.setState(...)
won’t immediately update this.state
. Instead, it’ll schedule an update which will occur sometime before the next repaint, but probably not before the method that called setState
finishes executing. If you need the current value of this.state
to compute the next value, pass an updater function. And if you need to know when the update completes, you can pass a callback.
If you don’t set this.state
, it defaults to undefined
. So if your component makes use of state, you’ll make your life a whole lot easier by setting an initial value in the constructor.
There’s one catch: you can’t call setState
within the constructor. Instead, use simple assingment:
constructor() {
this.state = {
// initial state
}
}
setState
within render
A class component’s render
method is for rendering. All it should do is figure out how to convert this.props
and this.state
into a React Element. That’s it.
But with this said, sometimes you do need to set some state after each render. And React provides a way to do this, called lifecycle methods. You won’t often need these, but we will touch on them later.
state
, don’t use itState adds complexity to your component. And while necessary complexity is… necessary, unnecessary complexity is going to come back and haunt you.
Practically speaking, this means that if you can compute something from props
instead, you should do so. The only time you should cache a computation in state
is when you’ve measured a significant performance benefit from doing so.
Of course, when you do need setState
, it is invaluable. And now that you’ve read the fine print, let’s talk about why you’ll actually need it.
So far, this course has focused exclusively on function components. And with good reason, too! They’re simple, and they let you accomplish a great deal.
But consider this: the whole reason that you’d want to use components — indeed, the reason for using React itself — is that it lets you encapsulate and re-use functionality. Function components are great at encapsulating presentation. But to encapsulate behavior, you’ll need class components and state.
The ability to store state opens up a world of possibilities. With class components, you can create:
And as you’ve probably guessed, storing user input allows you to build forms!