Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
229 views
in Technique[技术] by (71.8m points)

javascript - constructor vs componentWillMount; what a componentWillMount can do that a constructor cannot?

As far as I could see, the only thing a componentWillMount can do and a constructor cannot is to call setState.

componentWillMount() {
    setState({ isLoaded: false });
}

Since we have not called render yet, a setState in componentWillMount will prepare the state object before we enter the first render() pass. Which is essentially the same thing a constructor does:

constructor(props) {
    super(props);
    this.state = { isLoaded: false };
}

But I see another use case where componentWillMount is useful (on server side).

Let's consider something asynchronous:

componentWillMount() {
    myAsyncMethod(params, (result) => {
        this.setState({ data: result });
    })
}

Here we cannot use the constructor as assignment to this.state won't trigger render().

What about setState in componentWillMount? According to React docs:

componentWillMount() is invoked immediately before mounting occurs. It is called before render(), therefore setting state in this method will not trigger a re-rendering. Avoid introducing any side-effects or subscriptions in this method.

So, here I think React will use the new state value for the first render and avoids a re-render.

Question 1: Does this means, inside componentWillMount, if we call setState in an async method's callback (can be a promise callback), React blocks initial rendering until the callback is executed?

Having this setup on client-side (yes I see that use case in server-side rendering), if I assume the above is true, I will not see anything until my asynchronous method completes.

Am I missing any concepts?

Question 2: Are the any other use cases that I can achieve with componentWillMount only, but not using the constructor and componentDidMount?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Does this means, inside componentWillMount, if we call setState in an async method's callback (can be a promise callback), React blocks initial rendering until the callback is executed?

No, see here.

The following code doesn't block render (bear in mind this would be an anti pattern anyways to call setState there)

componentWillMount: function() {
     new Promise((resolve, reject) => {
        setTimeout(()=> {
            resolve();
        }, 2000)
     }).then(() => this.setState({ promiseResult: 'World' }));
  },

Question 2: Are the any other use cases that I can achieve with componentWillMount only, but not using the constructor and componentDidMount?

No, for ES6 classes you can discard componentWillMount. It is only needed if you use React.createClass({... })

EDIT: Apparently, I'm wrong. Thanks to @Swapnil for pointing this out. Here is the discussion.

React throws a warning if there is a side effect in the constructor which modifies state in another component, because it assumes that setState in the constructor itself and potentially during render() is being called. So no side effects in the constructor are desired.

This is not the case if you do it in componentWillMount, no errors are thrown. On the other hand, the guys from facebook discourage side effects in componentWillMount also. So if you don't have any side effects, you could use the constructor instead of componentWillMount. For side effects it is recommended to use componentDidMount instead of componentWillMount. Either way, you don't need componentWillMount.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...