-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
Make withRouter() update in response to context changes #3439
Comments
Do we want |
Yeah, that fix probably should have been done to @taion beat me to it, but the only issue I see is adding another layer to every |
We could change the context helpers to be React old-style mixins. This would remove the need for extra wrappers in both cases. Since they are not public API I think it’s a sensible compromise. |
To clarify, I don't have a strong opinion here – if you feel that it's better to have a single |
The issue isn't the context helper code, it's adding the |
If we make context helpers mixins, we can use them both from |
The problem is that we already added extra layer to |
Unless we want to use mixins, we're already adding an extra layer for the context subscriber. I think I'd go with the extra HoCs over using React mixins. At least start like this and see if people complain about the extra wrappers? Should be easy enough to cut things over to mixins if the extra elements become an issue. |
The upside of using mixins is less deep tree. People have already been complaining about the bunch of stuff at the root that makes navigating React / Redux / React Router apps difficult in React DevTools. We don’t have to make it worse. Generally mixins can be problematic from maintenance point of view but to me if feels like the exact situation where they solve a problem elegantly. When React fixes context, we can drop those mixins and forget about them, and consumers don’t have to dig through deeper trees just because of that issue. Those mixins are also never leaked to public API. Why do you view using mixins for this as problematic? |
This project has been moving away from them for the last few releases. They are entirely gone in 3.0. I think it's just an aversion to something that's viewed as being "in the past". ES2015 classes have gained prominence now that browser support is coming online and they are view as "the future". |
I don’t think I strike anyone as a proponent of mixins though 😄 . Mixins introduce implicit dependencies that make the project hard to refactor. This is why I don’t recommend using them in apps, and I understand why RR wanted to get away from them internally. This case is special because those mixins aren’t a way to share data or add functionality. It’s just a way to patch a bug in React with a workaround that can be cleanly removed when it’s unnecessary. Fixing it with mixins is less invasive than with HOCs. HOCs are useful to explain the data flow but there is no data flow here: we’re just patching over a bug. This is why I think making an exception in this particular case is completely worthwhile. |
FWIW, React doesn’t plan to drop support for mixins any time soon, so this is purely psychological. If we see them as solving a use case, we can use them. |
Oh yeah, I don't think they're going anywhere. It's the typical JS dev's way of thinking: "If I don't have a blank What if const contextClass = buildContextClass('router')
contextClass.render = () => (<WrappedComponent {...this.props} router={this.context.router} />)
const WithRouter = React.createClass(contextClass) |
I think mixins are fine here if we want to keep using I agree that we don't want to see: <ContextSubscriber(WithRouter(Link))>
<WithRouter(Link)>
<Link />
</WithRouter(Link)>
</ContextSubscriber(WithRouter(Link))> But to go back to the original question, do we want to have <WithRouter(Link)>
<Link />
</WithRouter(Link)> I'm still (marginally) inclined toward "no" on the latter. |
I might be wrong but I think you’re reinventing mixins 😄 . They already do a ton of useful stuff for our use case. For example, they merge lifecycle methods and state so mixins can do their hacky thing with |
Not exactly my re-invention 😛 wondering if we wanted to move off of |
I agree, I’d keep it just a |
|
Sorry, I was referring to #3439 (comment). I’d say writing any custom merging code is brittle and we’d have to remember about it. On the other hand, React mixins already know how to merge all the lifecycle methods correctly. So I don’t see the point.
For these two helpers, I think staying with it is fine.
The class generated by function withRouter(WrappedComponent) {
return React.createClass({
mixins: [ContextSubscriber('router')], // remove this line when React fixes context
...
render() {
return <WrapperComponent {...this.props} router={this.context.router} />
})
}
var Link = React.createClass({
mixins: [ContextSubscriber('router')], // remove this line when React fixes context
...
}) |
I don't think we need |
@timdorr I agree. I’m not using it for |
No, but @taion and I were talking about wrapping |
Agreed, I thought this might be nice in the beginning but I don’t think that anymore. Let’s keep things flat. |
To sum up, my proposal is the following:
This is the missing piece to making React Router work with Redux really well. The hierarchy is also flatter which makes debugging easier and performance marginally better. |
We actually made the decision to switch back to |
I'm on board with that. I was going to spend some time later today to pull out the context hack stuff (so I could use it in other libraries) and I can move stuff to mixins, but I'd be fine with someone else mixin-ifying the helpers too 😆 |
I’m a bit busy today so I’d appreciate if you did it as part of the transition. |
I don't know either 😄 otherwise I would have done it already. I think it might have to be in |
Please see #3440 as first part of this. |
And #3442 as the second part. |
#3443 is the last part that closes the issue. |
@timdorr Missed it, thanks! |
I wonder if you’d be up for accepting a PR like #3430 but for
withRouter()
(#3352). This would eliminate the problem of “how do I connect to the router state in Redux in a deep component” because people would just wrap their deep components withwithRouter
and be guaranteed to get the rightparams
.If this makes sense to you, I’d submit a PR that moves the context fix to be used by
withRouter
, and changeLink
to usewithRouter
internally.The text was updated successfully, but these errors were encountered: