1

I am making a react application. I need to make an ajax call to fetch the data from server and populate this data in the rows of my component's table. I do my ajax call in componentWillMount and store the response in the state. Now my render fetched this state and populates it. I have a few questions though:

  1. Am I doing it right to place ajax in componentWillMount?
  2. My componentDidMount doesn't get the value of state which get's set in componentWillMount. This means the async is not complete while componentDidMount is trying to access it. How to solve this? setting async:false is really a bad option.

  3. What all thing can be used in componentWillMount?

Finwe
  • 6,372
  • 2
  • 29
  • 44
EdG
  • 2,243
  • 6
  • 48
  • 103

2 Answers2

2
  1. Yes, componentWillMount is called once before the render. This is the place to fetch data.

  2. Probably when the component finished rendering, the componentDidMount called although the async operation didn't finished yet, therefore you get empty result.

You can use componentWillUpdate

componentWillUpdate() is invoked immediately before rendering when new props or state are being received. Use this as an opportunity to perform preparation before an update occurs. This method is not called for the initial render.

Or shouldComponentUpdate,

shouldComponentUpdate() is invoked before rendering when new props or state are being received. Defaults to true. This method is not called for the initial render or when forceUpdate() is used.

  1. It's a broad question, basically fetching data from actions, calling api's etc.

More info in docs

omri_saadon
  • 10,193
  • 7
  • 33
  • 58
  • so where can I perform the operation which uses the state which gets set in componentWillMount? Should I perform the operation in componentWillUpdate? – EdG Nov 01 '17 at 14:15
  • Yes, inside `componentWillUpdate()` you insert a condition that checks whether the result from the async operation is inside the state, if so you can proceed with your logic. – omri_saadon Nov 01 '17 at 14:17
  • There is no room for "if so" actually. I need to perform that operation by any means. What would be the best approach? – EdG Nov 01 '17 at 14:19
  • What do you mean? `componentWillUpdate(nextProps, nextState) {if (nextState.dataFromAsync) {doSomething()}}` – omri_saadon Nov 01 '17 at 14:24
1

Am I doing it right to place ajax in componentWillMount?

The recommend approach is to place your initial network requests that modify state inside of componentDidMount, because in theory your ajax request could come back prior to React completing the mounting process which might lead to your state getting overwritten.

However, in practise people use both as the above scenario should never happen.

My componentDidMount doesn't get the value of state which get's set in componentWillMount. This means the async is not complete while componentDidMount is trying to access it.

That is the correct behaviour.

How to solve this? setting async:false is really a bad option.

If you stop it then it's no longer async.

The best practise here would be to show a loading indicator:

  1. add a loading property to state
  2. set it to true just above your fetch request
  3. inside .then and .catch set loading to false
  4. inside render check if your data has arrived - if not display the loading indicator

If you don't want to show anything until your request comes back

You can return null inside of render which will prevent your component from being added to the DOM. You can then combine this with a flag state property to make sure the component gets mounted once your request comes back, i.e. something like this:

render() {
   if (!this.state.initialRequestHasCompleted) return (null);
   return (
      <div>
         ...
      </div>
   );
}

What all thing can be used in componentWillMount?

What is the purpose of having functions like componentWillMount in React.js?

linasmnew
  • 3,907
  • 2
  • 20
  • 33