I saw this line as an answer to another question on here:
"ponentWillMount should be ponentDidMount, or else you'll leak event emitters in node."
and I don't really understand it. Can someone explain with more detail?
More info:
Building a react application with flux, as part of the initial render, a child ponent putes some data. Ideally, after this data is puted, I would like to call an action that updates the store's state with a portion of this new data.
Normally, updating the store's state emits a change event that causes a re-render. However, because the change listener isn't being added until ponentDidMount (rather than in ponentWillMount), my top level ponent isn't able to listen for the change that occurs during the initial render and initiate a re-render.
If I move the addChangeListener to ponentWillMount that would seem to fix this issue, but the above quote suggests that this is a bad idea?
I saw this line as an answer to another question on here:
"ponentWillMount should be ponentDidMount, or else you'll leak event emitters in node."
and I don't really understand it. Can someone explain with more detail?
More info:
Building a react application with flux, as part of the initial render, a child ponent putes some data. Ideally, after this data is puted, I would like to call an action that updates the store's state with a portion of this new data.
Normally, updating the store's state emits a change event that causes a re-render. However, because the change listener isn't being added until ponentDidMount (rather than in ponentWillMount), my top level ponent isn't able to listen for the change that occurs during the initial render and initiate a re-render.
If I move the addChangeListener to ponentWillMount that would seem to fix this issue, but the above quote suggests that this is a bad idea?
Share Improve this question asked Jun 17, 2015 at 17:37 hmleehmlee 8871 gold badge9 silver badges23 bronze badges2 Answers
Reset to default 4I think the prevailing wisdom that listeners should be set in ponentDidMount
because it prevents problems in isomorphic applications is a mistake. I think in 98% of cases for non-isomorphic applications setting listeners in either ponentWillMount
and ponentDidMount
will work the same way, but it is conceptually wrong and in the 2% of cases (such as the example given in the original question) it will do the wrong thing.
There are git issue discussions and ments in the React source code suggesting that it would be preferred that ponentWillMount
wasn't called on the server at all, but if it isn't then problems are created in the checksum test paring the server prerender to the client initial render. Having ponentWillMount
on the server means that it isn't executed as part of the ponent lifecycle in this case, but this is being used as an excuse to not count it as part of the lifecycle in any case.
In fact, ponentWillMount
is exactly the right place to register listeners if you are not creating an isomorphic application. If you are creating an isomorphic application then you have to make some promises due to the checksum/lifecycle issue not being ideal in this case (maybe just testing for the server environment and then not registering listeners?).
In non-isomorphic applications adding listeners in ponentWillMount
can save unnecessary re-renders in some cases and will register them in document order. The advantage of document order is that if you have a way to flush pending events as ponents are re-rendered (for example, takeRecords
on a MutationObserver
) then you can ensure the document is re-rendered top down instead of bottom up, converting the rendering plexity to linear from polynomial.
Additionally, there is no danger period between the initial render and when the listener is registered where the Store can change without triggering a render, causing the view to be out of sync with the Store (the example problem given in the original question). If the listener is registered in ponentDidMount
you either need to make sure the Store isn't changed in ponentDidMount
calls in children, or else force a re-render/re-sync after registering the listener, which if done in ponentDidMount
is done in reverse document order which may be polynomial plexity (depending on how/if the React setStates
are aggregated).
Is hard to understand what that quote means without more context. What I can tell you is that there are huge differences between the two of those methods.
On one hand, ponentWillMount
is called before the ponent is actually added to the DOM. This is the last chance you have to update ponent's state and get it rendered before the ponent is rendered by the browser.
On the other hand, ponentDidMount
is called once the ponent has been attached to the DOM (the real one).
What you need really depends on your use case. In general, ponentDidMount
is used to integrate with other libraries (like jQuery), it provides a way to modify the HTML rendered by the ponent.
I suggest you to read these links:
- https://facebook.github.io/react/docs/ponent-specs.html#mounting-ponentwillmount
- https://facebook.github.io/react/docs/ponent-specs.html#mounting-ponentdidmount
- https://facebook.github.io/react/tips/use-react-with-other-libraries.html