-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds react15CompatibilityMode setting #540
Conversation
@@ -20,7 +20,7 @@ function warnAboutReceivingStore() { | |||
|
|||
export default class Provider extends Component { | |||
getChildContext() { | |||
return { store: this.store } | |||
return { store: this.store, react15CompatibilityMode: this.props.react15CompatibilityMode } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be on <Provider>
. It's on a per-component basis, like pure
. I wouldn't worry about context at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provider is where you set the default, so you don't have to change it on every single connected component when you want the new behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But you shouldn't be blanket applying a perf-reducing setting when it may not apply to most connected components. Just make it default at the connect()
level and remove the context stuff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I interpreted @gaearon's messages as we wanted to impose the least amount of breaking changes as possible, that's why I made it a global default setting which is "work like it used to, even if that means being not as fast as possible and maybe get stale props". It's certainly less code in react-redux to not have a global setting and require devs to go enable the compat setting on all their connected textboxes. I'm fine with either approach but I just need to be told which way we're going.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, and for 5.0 it will be opt-out of the slower (but more compatible) behavior. For 5.1, which will wait on React 16, it will be opt-in for those who need to stick with React <=15.
Have you run any perf tests on this? I assume it basically gets us back to 4.0 levels of speed, correct? That should be fine, since we're not regressing on speed at all. We can make a big warning label at the top of the release notes about it so no one misses the opt-out. |
@timdorr Currently swamped with other things. Will perf test when I have a large block of time. Hopefully this weekend. |
Added a commit to remove the Provider API as requested. Again, we should be having people set this on a per-component basis, defaulting to Also, I rebased this against the latest |
@timdorr why remove the provider api? I want to use this compat mode for redux-form components but want everything else in the app to use the efficient sub ordering. Having to set this on each connected component seems an unnecessary chore. have it be defaulted to true in 5.0 but why make opting into performance more difficult than it needs to be? |
Just wrap connect and curry the options: export function fastConnect(a,b,c,options) {
return connect(a,b,c, { react15CompatibilityMode: false, ...options })
} (On my phone, so I hope that came out right...) |
This works but it also means code modding / find replacing a large number of files with the need to do so again as soon as 5.1 comes out. I'm not adamant that this get added back in but the trade offs aren't cost free for users ( I realize they aren't cost free for the lib either since it requires supporting ). I could be misguided here but I think the cost is higher on lib consumers. Just lending my annecdote to @jimbolla intuition that a configurable global default might be desired. |
@timdorr I'll concede taking it out of provider, but we should leave in the ability to pass the setting from props/context. Props is especially important if you want to control it through a library such as redux-form that hides the |
Sorry, I'm not trying to be dismissive. Obviously I want this to be an awesome release for most users. I haven't run into a situation like this before where we essentially need to define a global to configure a library. I do want to get this right and not just shove something somewhere, because I feel like we'll live to regret that decision 😱 What about a singleton module? import { render } from 'react-dom'
import { setReact15CompatibilityMode } from 'react-redux'
setReact15CompatibilityMode(false)
render(<Provider store={store} children={appyStuffs} />, root) It could also be generic: |
Would it make sense to just put the method on connect instead of being a top level export? Like this: connect.setReact15CompatibilityMode(false); I think it makes it more clear that it's a setting that affects |
Frankly it all seems ugly any way you look at it, but I could get behind adding a method to |
@jimbolla Yeah, I think that works better. Maybe call it |
…patibilityMode function.
Added |
@jimbolla @timdorr @markerikson thanks all |
Cool. Let's do this thing! |
* Adds react15CompatibilityMode setting as temporary fix for reduxjs#525 * Remove Provider API for react15CompatibilityMode. * Fix tests against react15CompatibilityMode. * adds defaultReact15CompatibilityMode setting and setDefaultReact15CompatibilityMode function.
react15CompatibilityMode
is intended to be a temporary setting until our official solution is "use React v16." When set to true, which is the default in<Provider>
, subscriptions are not re-ordered to fire top-down. This avoids the bug related to #525 but loses some of the perf gains and re-introduces the issues with state and ownProps being out of sync. This should behave pretty much like react-redux v4.A developer that upgrades to this version w/o making any other changes should not experience the #525 bug out of the box, but won't get the good stuff mentioned above.
The recommended upgrade path is to set
react15CompatibilityMode
to false at the<Provider>
level and then set it to true at the component level for allconnect
ed text inputs. This can be done either as a prop (confirmed working with redux-form's<Field>
component) or as an options arg toconnect
. Those inputs are now vulnerable to the state/props sync issue that exists in v4, but will not have the #525 cursor issue.Apps using React v16 (or whatever version includes facebook/react#8204), or using Preact as a drop-in replacement for React should not have to set
react15CompatibilityMode
to true at the component level at all... just set<Provider react15CompatibilityMode={false}>
.Once React v16 becomes the popular choice, we can switch the default from true to false. Once v15 support is dropped, we can backout this change completely.