Skip to content
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 inside static containers #3443

Merged
merged 4 commits into from
May 9, 2016

Conversation

gaearon
Copy link
Contributor

@gaearon gaearon commented May 9, 2016

Fixes #3439.

if (eventIndex !== this.state[lastRenderedEventIndexKey]) {
if (this.context[name] !== nextValue) {
// React uses a stale value so we update it manually.
this.context[name] = nextValue;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not proud of this but it works fine. I’ll keep an eye on this not breaking in the React repo 😄

@@ -43,8 +43,9 @@ export function ContextProvider(name) {
},

componentDidUpdate() {
const nextValue = this.getChildContext()[name]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is safe because React makes no guarantees about when this method can be called

@taion
Copy link
Contributor

taion commented May 9, 2016

I think on net this is a bit messier than the earlier implementation that just updated the router object in-place.

@gaearon
Copy link
Contributor Author

gaearon commented May 9, 2016

Yea. On the other hand, this keeps the desired property of Context* being generic. If they aren’t updating context to new objects, I’m not sure how much useful they would be as an outside module.

@taion
Copy link
Contributor

taion commented May 9, 2016

I mean, it's an unfortunate caveat to have, but I'm guessing it's probably slightly more performant to not recreate the object every time. Having to keep the same object identity is a caveat that I can live with.

@gaearon
Copy link
Contributor Author

gaearon commented May 9, 2016

it's probably slightly more performant to not recreate the object every time

I think this would only be relevant if navigation was something that’s performed hundreds of time per second. I wouldn’t expect this to have any measurable performance in this particular scenario.

Happy to change it though. You sure?

@gaearon
Copy link
Contributor Author

gaearon commented May 9, 2016

What I like about this is while it’s messier on the net, the messy bits are all in the “polyfill”. As opposed to spreading through the legit code.

@gaearon
Copy link
Contributor Author

gaearon commented May 9, 2016

I’m fairly content with what I posted before but I added 893cbf0 as a minimally invasive alternative approach. It adds object-assign as a dependency but React already uses it anyway.

@taion
Copy link
Contributor

taion commented May 9, 2016

cc @jquense who's done some stuff to work around this issue. At this point I'm really torn.

@gaearon
Copy link
Contributor Author

gaearon commented May 9, 2016

Ultimately we can go either way and switch if we find problems later. I’d probably use the last commit because it doesn’t touch this.context so if React (unlikely) adds a warning on setting to it, this wouldn’t affect us.

@taion
Copy link
Contributor

taion commented May 9, 2016

Yeah, I'm fine with imposing a bit of extra work on the users of this polyfill I think. Probably I'd be happier mutating my context objects in place rather than worrying that setting this.context will break. It's all a workaround anyway.

@gaearon gaearon merged commit f64659d into remix-run:next May 9, 2016
@gaearon gaearon deleted the with-router-static branch May 9, 2016 19:53
@gaearon
Copy link
Contributor Author

gaearon commented May 9, 2016

In case we want to change the mind later, the test case I added should catch any mistakes.

@taion
Copy link
Contributor

taion commented May 9, 2016

I'm happy with this for now.

@gaearon
Copy link
Contributor Author

gaearon commented May 9, 2016

@taion One last problem is this still doesn’t update containers with shallow equality check. We can either revert the last commit or add a bogus prop just to force an update.

@gaearon
Copy link
Contributor Author

gaearon commented May 9, 2016

Alternatively, we can inject params and location as props to withRouter(), in addition to router itself. Then it wouldn’t matter.

@taion
Copy link
Contributor

taion commented May 9, 2016

You mean in case someone does withRouter(connect(whatever)(MyComponent))?

@gaearon
Copy link
Contributor Author

gaearon commented May 9, 2016

Yeah. That’s the primary use case I’m trying to get support for because it’s very common in Redux apps.

@taion
Copy link
Contributor

taion commented May 9, 2016

I like the idea of withRouter injecting the additional props – makes withRouter-ed components work identically to route components, which seems like a nice symmetry.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 19, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants