First of all let’s understand why do we even need states.
Props are Read-Only
We saw earlier in this Components and Props in React post that you can declare the components in two different ways. No matter which method you use to do so, one thing is clear. It must not modify its props.
That’s where the states concept comes into play.
With States React Components can change their output based on events.
In this Rendering Elements Example, we saw how to change the element. Just rendering the same element again and again. But we don’t need to do that. We can just simple change the state of that element and change the UI.
Here’s the working example:
In the example above, we are Rendering the element to change the output but not changing the states. Let’s try to achieve the same outcome by changing the states.
Let’s change the way clock looks first (encapsulation):
Still, in the updated code above, Clock component is not updating the UI itself.
We need to have ReactDOM.render like this and inside the Clock component we’ll change the states so that the clock can update itself.
ReactDOM.render( , document.getElementById('root') );
Function to Class
To do so, we need to convert the function component into a class component and then add state to it.
States are similar to props but they are private and fully controlled by the component class.
Let’s convert the function into a class and update the code:
In the updated code above, the render method will be called each second as setInterval calls tick function every second.
What we have changed is we render the element into the same DOM so there will be only one instance of the Clock class that will be used. Since we have one DOM and one instance of the Clock class, we can use the local state and lifecycle methods on it.
We can make use of this post: How to add Local State to a Class in React?
Here’s the updated code after following those steps:
Now, it’s time to add lifecycle methods. We can make use of this post: How to add Lifecycle Methods to a Class in React?
After that, all we need to do is implement a method called tick(). The Clock component will run tick() method every second.
The tick() method will use this.setState() to schedule updates to the component local state.
Here’s the updated code:
This is what happens in the final code:
- When we pass Clock element to ReactDOM.render(), it’s going to call base constructor of Clock component. That will set its state to the current time using this.state.
- React will go for the render method to check what to display and show the output.
- When the output is displayed in the DOM, React will check for componentDidMount method which will set a timer in the browser to call tick method every second.
- Browser does as instructed and calls tick method every second.
- The tick method updates the state with a new time.
- React understands the change in state and calls render method again to update the DOM.
- If you remove Clock component from the DOM then React will call componentWillUnmount method and stop the timer.
Source: React Docs