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

React Router is uncontrolled with respect to query state #4889

Closed
dminkovsky opened this issue Mar 31, 2017 · 6 comments
Closed

React Router is uncontrolled with respect to query state #4889

dminkovsky opened this issue Mar 31, 2017 · 6 comments

Comments

@dminkovsky
Copy link

dminkovsky commented Mar 31, 2017

I understand the motivation for not parsing query strings in V4 (i.e. #4410 and #4527). I understand I can parse the query string myself.

Since the query is part of a component's props, components can render based on the query. But since React Router does not react to changes in the query string, a change in the location's query does not cause it update.

What you get is a strange sort of half-coupling to the query state. This is particularly strange given that <Link to /> can accept a location object, which might specify a query. Navigating to such a link, however, will not do anything if only the query string changed.

The only solution I've come up with is to duplicate the query state on the component. The component is initialized with state from the query string, and then changes to the query string must also update the component state.

Am I missing a better way to handle this issue?

@pshrmn
Copy link
Contributor

pshrmn commented Mar 31, 2017

However, components can render based on the query. For such components, a change to the location's query does not cause it update. This is because nothing changes anywhere in terms of state known to React.

When you navigate within React Router, you pass a location string or object to the history object. history then creates a new location object. history then informs the <Router> that the location has changed and the <Router> re-renders the application.

I'm having a hard time understanding the issue that you're having, but there shouldn't be a problem with components not updating because only the search string changes. To demonstrate this, I threw together a quick codepen with links that just change the location.search property.

If I'm missing something, please include some example code.

@timdorr timdorr closed this as completed Mar 31, 2017
@dminkovsky
Copy link
Author

thank you @pshrmn!

It took me a while but I found a way to replicate: http://codepen.io/anon/pen/vxvQdN. I changed component to render in <Route />, which is, indeed, how my application is using <Route /> The re-render does not take place.

@dminkovsky
Copy link
Author

dminkovsky commented Mar 31, 2017

Oh whoops. I merely broke your example. My apologies. I will continue trying.

@dminkovsky
Copy link
Author

dminkovsky commented Apr 1, 2017

Okay, I am back to explain myself :).

First, thanks again @pshrmn for your reply and your demo code. Not sure why I didn't do this. Where do I send the check?

I took a deep dive and I identified my problem. The issue was related to my transition from v4-beta.5 to v4.0.0. I had made the transition, didn't notice the transition broke everything, and then assumed the issue was just with query strings, which I had just then tried using for the first time in this app!

But here is what happened: In beta 5, Routes listen to the router directly. This listening is set up in componentWillMount. The listener triggers a forceUpdate(). So even if a parent component returns false from shouldComponentUpdate(), the child Route works outside the React paradigm and updates anyway.

In v4.0.0, Route is more true to the standard React way of doing things and does not directly subscribe to its parent router beyond the scope of its props and context. If a parent component does not update in response to a location change, neither will the Route. In my case, I had a Route wrapped inside a Relay.Container which was returning false from its shouldComponentUpdate. So when I updated from beta 5 to 4.0.0, everything broke. But, I did not notice.

Thanks again for your response, and sorry for posting this inane issue!

@pshrmn
Copy link
Contributor

pshrmn commented Apr 1, 2017

Oh, sorry, I probably could have saved you some time if I had included the link to the blocked updates guide. I think that when I was originally writing my response, I included it, but since you mentioned query specifically, I thought the issue was with you using location.query, which is no longer a thing.

I'm working on putting together a FAQ and the blocked updates problem is at the top of the list, so hopefully fewer people will be running into the same issue as time goes on.

@dminkovsky
Copy link
Author

Well I'm glad I finally dug into this codebase. I last looked at version 3, which I never got my head around. This version was basically immediately approachable due to the React idiomatic approach. So at least this layer of my stack is now demystified :).

@lock lock bot locked as resolved and limited conversation to collaborators Jan 20, 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

No branches or pull requests

3 participants