fromWhy send requests inside componentDidMount?

When we write React code, we always run into the problem of requesting the interface and displaying the data we’ve retrieved. It sounds simple enough, but have you ever wondered when it’s best to make an Internet request? I’m sure you’ll all say, of course I know it’s in componentDidMount, because React officially recommends it

I think that’s enough for you? Yes, but why componentDidMount? Constructor or componentWillMount not ok?

First of all, let’s do a Search on Baidu. This is the most popular answer

To sum up:

  1. ComponentDidmount is not executed until the component is fully mounted, calling setState in this method triggers rerendering, and best of all, it’s officially recommended!

  2. The constructor call is started when the component is not mounted and therefore not available.

  3. ComponentWillMount is called after constructor, and the code calling setState here will not start rendering again, so no.

  4. Another common refrain that doesn’t appear here is that making web requests in componentWillMount blocks component rendering.

  5. Anyway, it’s going to be used in componentDidmount!

It seems to make sense, but it also feels strange. It is better to test yourself than to see more. First test constructor.

constructor

class Parent extends React.Component {
  constructor(props) {
    super(props);
<span class="hljs-keyword">this</span>.state = { <span class="hljs-attr">text</span>: <span class="hljs-string">'plain text'</span> }; fetch(<span class="hljs-string">'https://s.codepen.io'</span>) .then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt; </span> <span class="hljs-keyword">this</span>.setState({<span class="hljs-attr">text</span>: <span class="hljs-string">'success'</span>})) .catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt; </span> <span class="hljs-keyword">this</span>.setState({<span class="hljs-attr">text</span>: <span class="hljs-string">'error'</span>}))Copy the code

}

render() { return (

{this.state.text}

); }}
Copy the code

ReactDOM.render(
<Parent/>.document.getElementById('root'));Copy the code

State changed from plain text to error (the request could not succeed because of cross-domain problems, but that doesn’t matter)

The component can send a request when it is not mounted. The time affected here is only the time to execute the sending request, and then the component continues to render and wait for the asynchronous data to return before executing setState. You might say, if the request is short, What if it returns before the component is mounted, and does setState still matter? Don’t worry, the question will come up later.

componentWillMount

Move the request to componentWillMount


class Parent extends React.Component {
  constructor(props) {
    super(props);
<span class="hljs-keyword">this</span>.state = {
  <span class="hljs-attr">text</span>: <span class="hljs-string">'plain text'</span>
};
Copy the code

}

componentWillMount() {
fetch('s.codepen.io')
.then(res => this.setState({text: 'success'}))
.catch(err => this.setState({text: 'error'}))
}

render() { return (

{this.state.text}

); }}

ReactDOM.render(
<Parent/>,
document.getElementById('root')
);

Copy the code

Copy the code

If the state is changed from plain text to error, you can use setTimeout to simulate it. WillMount does not re-render setState. Don’t network requests block component rendering? Constructor affects only the time it takes to execute the sent request and does not block component rendering. There are other reasons why using componentWillMount is not recommended:

  1. Is very important, will be abandoned after React16.3 componentWillMount, componentWillReceiveProps and componentWillUpdate three periodic function, until 17 before you can also use the React, But there will be a caveat.

  2. Fetch data will be executed twice, once on the server and once on the client. This is not the case with componentWillMount.

SetState puts the updated state in the component’s __pendingStateQueue queue. React does not respond to the update immediately. It will wait until the component is mounted before updating the dirty component. See below

Therefore, from another perspective, it is more efficient to put it inside constructor or componentWillMount.

conclusion

  1. Data retrieval can be placed in Constructor or componentDidmount, not componentWillMount. But for better code specification and readability, it is recommended to place componentDidmount uniformly.

  2. There is no data for the first render, which could lead to errors. You can set an initial state or add a loading state, and display a spinner or skeleton diagram when loading data are common solutions.

Refer to the link

  1. Where to Fetch Data: componentWillMount vs componentDidMount

  2. React Data fetch why must be called inside componentDidMount?