Gaurang Shah
Gaurang Shah

Reputation: 12960

Render is called twice when fetching data from a REST API

I am trying to interact with a REST API using React, and I have realized that when I fetch the data, render is called once without the data, and then again with the data.

This throws an exception when I try to process this data, but I can use an if statement to check if data is null or not. However, I am not sure if that's needed.

class App extends Component {
  state = {
    TodoList: {},
  };

  componentWillMount() {
    axios.get("http://localhost:5001/1").then((response) => {
      this.setState({
        TodoList: response.data,
      });
    });
  }

  render() {
    console.log(this.state);
    return <h1>hello </h1>;
  }
}

This is what I see in in the console: enter image description here

Upvotes: 5

Views: 11822

Answers (3)

Isaac
Isaac

Reputation: 12894

That's perfectly normal.

Your App component flow as below:

  1. Execute render method to load the component
  2. execute codes in componentDidMount
  3. Calling axios.get which is async operation
  4. Receive data from step 2, update component state by using this.setState
  5. App component detected there's an update on state, hence execute render method to load component again

Hence, you should definitely handle the case where this.state.TodoList has no data, which happened at first load

UPDATES:

component lifecycle componentWillMount is now deprecated which means you shouldn't be using it anymore. Replace it with componentDidMount instead. Functionally wise they should be no difference in your example

Upvotes: 4

Piyush
Piyush

Reputation: 3285

  1. Initially, render method is called after cwm method. So console log shows the state's empty value first time.

  2. But you have run an async operation in cwm method, so after it is done, the setstate method is called which causes the render method to run again.

Note: ComponentWillMount, componentWillUpdate and componentWillUpdate props method are deprecated.

You should move this API call to componentDidmount or ComponentDidUpdate method.

However, event after this, your console log will appear twice- one for initial render and second for setstate called after API call.

Upvotes: 1

Meet Zaveri
Meet Zaveri

Reputation: 3059

Note : componentWillMount is deprecated and will work until version 17.

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

Most suitable React Lifecycle for calling APIs: componentDidMount is the most prefered method to perform asynchronous tasks like API calls, setTimeouts , etc..

It'll work as -

  1. On componentDidMount your API gets called

  2. As per lifecycle order, lastly render method will be called. (Still API hasn't returned response). Your UI is displayed at initial paint.

  3. Once API gets response, you use this.setState() which will force a re-render operation.
  4. Again your UI changes are updated

Remember : this.setState() will only be called once whether you have called it once or more than once in lifecycle method

Upvotes: 0

Related Questions