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().

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

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>