最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why should addChangeListener be in componentDidMount instead of componentWillMount? - Stack Overflow

programmeradmin6浏览0评论

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 badges
Add a ment  | 

2 Answers 2

Reset to default 4

I 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
发布评论

评论列表(0)

  1. 暂无评论