Setting state on componentDidMount()

I know that it is an anti-pattern to set state on componentDidMount and a state should be set on componentWillMount but suppose I want to set the length of the number of li tags as a state. In that case, I can't set the state on componentWillMount since the li tags might not have been mounted during that phase. So, what should be the best option here? Will it be fine if I set the state on componentDidMount?


Solution 1:

It is not an anti-pattern to call setState in componentDidMount. In fact, ReactJS provides an example of this in their documentation:

You should populate data with AJAX calls in the componentDidMount lifecycle method. This is so you can use setState to update your component when the data is retrieved.

Example From Doc

componentDidMount() {
    fetch("https://api.example.com/items")
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            items: result.items
          });
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

Solution 2:

According to the React Documentation it's perfectly OK to call setState() from within the componentDidMount() function.

It will cause render() to be called twice, which is less efficient than only calling it once, but other than that it's perfectly fine.

You can find the documentation here:

https://reactjs.org/docs/react-component.html#componentdidmount

Here is the excerpt from the documentation:

You may call setState() immediately in componentDidMount(). It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won’t see the intermediate state. Use this pattern with caution because it often causes performance issues...

Solution 3:

The only reason that the linter complains about using setState({..}) in componentDidMount and componentDidUpdate is that when the component render the setState immediately causes the component to re-render. But the most important thing to note: using it inside these component's lifecycles is not an anti-pattern in React.

Please take a look at this issue. you will understand more about this topic. Thanks for reading my answer.