constructor vs componentWillMount; what a componentWillMount can do that a constructor cannot?
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
.
yadhu
Updated on September 29, 2020Comments
-
yadhu over 3 years
As far as I could see, the only thing a
componentWillMount
can do and aconstructor
cannot is to callsetState
.componentWillMount() { setState({ isLoaded: false }); }
Since we have not called
render
yet, asetState
incomponentWillMount
will prepare the state object before we enter the firstrender()
pass. Which is essentially the same thing aconstructor
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 tothis.state
won't triggerrender()
.What about
setState
incomponentWillMount
? According to React docs:componentWillMount()
is invoked immediately before mounting occurs. It is called beforerender(
), 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 callsetState
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 theconstructor
andcomponentDidMount
? -
Swapnil over 7 yearsFor ES6 if I am using Redux and want to dispatch an action on initial load, it is suggested to dispatch the action in componentWillMount instead of the constructor. It says that over here
-
Swapnil over 7 yearsOne more thing. My name is Swapnil not Swapnii :p
-
Lyubomir over 7 yearsI need glasses;-)
-
yadhu over 7 years@leo, In the fiddle you shared I put a log inside
render()
. What I observed was, React renders a "Hello" on first render. Then after 2s, the timeout happens,setState
is called fromcomponentWillMount
. React updated the new state value on the DOM, though it did not re-render!! That's mysterious for me! How did it update DOM without re-rendering? (I am pretty sure, I am missing something here about React). -
yadhu over 7 yearsI am sorry, it was my eyes betrayed me!! You're right, yes it re-renders. Oh now I get it, the
setState
is not called fromcomponentWillMount
closure. It is called from another scope, the env of the call back function; thus triggered the render. So the react docs are right,setState
insidecomponentWillMount
does not trigger a re-render :)