Use componentWillMount instead of componentDidMount for subscriptions #320
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Even if this PR doesn't get accepted, I'm hoping to find out the reasoning behind the current implementation and find out what patterns to use to avoid the problem I found. The problem being...
Because component store subscriptions are created in
componentDidMount
(which fires child before parent), you can get into situations like this:Here's a simple example showing the problem:
https://jsfiddle.net/justindeal/myqyxpcw/6/
There's a value in the store 'a' or 'b' which is used to switch components
A
andB
. I have some side effect rendering to show what values are actually rendered byA
andB
. You can see thatA
incorrectly gets a 'b' value on the first toggle.By switching to
componentWillMount
, subscriptions are always in parent-child order, so there's never any inconsistent state.If you want to consider a simple real-world case, think about the filter string from the canonical todo example. Now consider that you can switch between todos and recipes. The filter for todos may make no sense for filtering recipes. So sending the global filter for todos to the child recipe components makes no sense and can cause errors to be thrown if unexpected props/values show up.
This change had one side effect for existing tests: because we haven't yet rendered when subscribing, the impure case avoids a duplicate initial call to its state mapping function. As far as I can tell, this has no effect on what's actually rendered though.
I also saw no negative outcome when I made the change for my app. (Just a fix to the surprising behavior I saw.) But I'm curious to get some feedback.
Thanks!