What is state in ReactJS and where to initialize it?

What is state in ReactJS?

A state inside a component is a plain JavaScript object. This state object can only be changed inside that component. Any change in the state object calls the component’s render() method.

As the state of a component cannot be changed by other components, we can call the state object as private object for that component.

When we should use state inside a component?

As we know that the responsibility of a component is nothing but render a piece of HTML into the DOM. Now when we see the rendered HTML needs to be changed based on user actions then we should use state object inside the component.

Where to initialize the state?

Inside a component if we do not set the initial value of state object then it is set to null. If we run the following code then we will see in browser console it prints null.

class App extends Component {
  render() {
      console.log(this.state);
      return (
          <div className="container">
          </div>
      );
  }
}

If we need a initial state for the render method of the component then it is a good practice to initialize it inside constructor method. In the lifecycle of React component mounting, the constructor gets called first. So, if we set the state inside the constructor then it will be available inside the render method. Here is how we should initiallize the state inside a component:

class App extends Component {
    constructor(props){
        super(props);
        this.state = {products: []};
    }

    render() {
        console.log(this.state);
        return (
            <div className="container">
            </div>
        );
    }
}

In the latest react, we now can define state as a plain JavaScript object and the render method gets it correctly. Here is an example of state as a plain object outside constructor:

class App extends Component {
    constructor(props){
        super(props);
    }
    state = {products: []}
    
    render() {
        console.log(this.state);
        return (
            <div className="container">
            </div>
        );
    }
}

What is the problem if we use componentDidMount to initialize state?

The method componentDidMount gets called after the execution of render() method. So, if we initialize the state inside componentDidMount lifecycle method then the render method gets call twice which is not good for performance. At the same time if the render method depends on the state data then the first render will fail.

class App extends Component {
    constructor(props){
        super(props);
    }
    componentDidMount(){
        this.setState({products: data})
    }

     render() {
         console.log(this.state);
         return (
             <div className="container">
             </div>
         );
     }
}
// First output: null
// Second output: {products: Array(0)}