React Class Component - Local State
Table of Contents
About
state management in class component
In React, mutable state is typically kept in the state property of components, and only updated with setState().
Articles Related
Rules
- Do Not Modify State Directly. Use this.setState(). The only place where you can assign this.state is the constructor.
- Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.
Wrong, this code may fail to update the counter.
this.setState({
counter: this.state.counter + this.props.increment,
});
Correct. Passes a function rather than an object.
this.setState(function(prevState, props) {
return {
counter: prevState.counter + props.increment
};
});
// or with the arrow function notation
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
- setState() merges the object you provide into the current state. You can update several props independently with separate setState() calls (ie setState calls are batched). The merging is shallow, so this.setState({comments}) leaves all other props intact (this.state.*) but completely replaces this.state.comments.
- Neither parent nor child components can know if a certain component is stateful or stateless, and they shouldn't care whether it is defined as a function or a class. This is why state is often called local or encapsulated. It is not accessible to any component other than the one that owns and sets it.
- A component may choose to pass its state down as props to its child components. This is commonly called a “top-down” or “unidirectional” data flow. Any state is always owned by some specific component, and any data or UI derived from that state can only affect components “below” them in the tree.
Process
- React may batch multiple setState() calls into a single update for performance.
Shared State
When a state is shared between components, the common technique is lifting up the state to their closest common ancestor. See React Class Component - Shared State (Lifting state up)
Example
- The Clock components with state using the lifecycle functions componentWillUnmount and componentDidMount. See React Class Component - Rendering (Mounting/Unmounting)
class Clock extends React.Component {
// Since Clock needs to display the current time, the constructor initializes this.state
constructor(props) {
super(props);
this.state = {date: new Date()};
}
// When the Clock output is inserted in the DOM, React calls the componentDidMount() lifecycle hook.
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
// Called if the Clock component is ever removed from the DOM, so the timer is stopped.
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
// Thanks to the setState() call, React knows the state has changed, and calls render() method again.
this.setState({
date: new Date()
});
}
// React learns what should be displayed on the screen.
// React then updates the DOM to match the Clock's render output.
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
- The classic Render and XML function. When <Clock /> is passed to ReactDOM.render(), React calls the constructor of the Clock component, then calls the Clock component's render() method.
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
<div id="root">
<!-- called the "root" DOM node because everything inside it will be managed by React DOM -->
</div>