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

Fix initial routing state after match #2965

Merged
merged 2 commits into from
Jan 27, 2016
Merged

Fix initial routing state after match #2965

merged 2 commits into from
Jan 27, 2016

Conversation

taion
Copy link
Contributor

@taion taion commented Jan 23, 2016

Fixes #2935

#2883 was actually busted and had a test that didn't cover what it was supposed to.

In an ideal world we'd just use the same history and transitionManager for match() and <Router> on the client side, but the deprecation wrapping API messes with that too much, so this might be the best we can do for now.

@taion
Copy link
Contributor Author

taion commented Jan 23, 2016

Actually, maybe not...

@@ -75,7 +76,7 @@ describe('server rendering', function () {
const AsyncRoute = {
path: '/async',
getComponent(location, cb) {
setTimeout(cb(null, Async))
setTimeout(() => cb(null, Async))
Copy link
Member

Choose a reason for hiding this comment

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

How did this even work before? :|

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It wasn't async before.

@taion
Copy link
Contributor Author

taion commented Jan 23, 2016

Don't merge this yet...

@taion taion changed the title Fix initial routing state after match [WIP] Fix initial routing state after match Jan 23, 2016
@taion taion changed the title [WIP] Fix initial routing state after match Fix initial routing state after match Jan 23, 2016
@taion
Copy link
Contributor Author

taion commented Jan 23, 2016

This is good to go now. The idea is to delegate the creation of the router and transitionManager to match() when possible, and just use those same objects (that now have all the correct state) in <Router> rather than creating new ones.

@@ -53,7 +53,7 @@ render(<Router history={history} routes={routes} />, mountNode)
You need to do

```js
match({ routes, location }, (error, redirectLocation, renderProps) => {
render(<Router {...renderProps} history={history} />, mountNode)
match({ history, routes }, (error, redirectLocation, renderProps) => {
Copy link
Member

Choose a reason for hiding this comment

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

How do you get location from the server request into match?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

browserHistory should already have it in the URL.

Copy link
Member

Choose a reason for hiding this comment

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

No, this is server rendering. How do I get req.url in there?

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 actually the "what to do on the client when using server-side-rendering plus async routes" section.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On the server, as above, you still match({ routes, location }) and render a <RouterContext>.

On the client, here, you match({ history, routes }) and render a <Router>. Since history is going to be some browser history, it doesn't need to be told its location.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, well that's just because we have shitty docs. What are "async routes"? I know what that means, but it's not explained anywhere else in the docs. This is an example of why they don't work and why we get so many of the same set of questions all the damn time.

Anyways, I do like that this neatens up the API a tad, as we don't have to pass through our history to the Router instance by hand. Sorry for the confusion here.

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 actually less bothered by this specific case – both async routes and SSR are relatively advanced, so the documentation around the intersection of the two doesn't need to target beginners.

It's not just "we don't have to pass through our history" in this case though – it's actually necessary that both match and <Router> use the same history, since the transition manager (that we want to re-use) is already bound to a history.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Circling back up on this – thoughts? In 3.0, the requirement ought to be either a history or a matchContext.

@timdorr
Copy link
Member

timdorr commented Jan 24, 2016

Can you cherry pick in 63ac75c or just merge in that branch instead? Just wanted to clean up some of that section in Router.

@taion
Copy link
Contributor Author

taion commented Jan 24, 2016

Updated.

...nextState,
history,
router,
matchContext: { history, transitionManager, router }
Copy link
Member

Choose a reason for hiding this comment

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

I get you're concerned that someone might have a mismatched history/transitionManager/router combo, but is that practically ever going to happen? This is entirely an internal-use, undocumented API, and if you use it, you'll need to learn how the code operates. In fact, you'll have to be reading through the code to even find it in the first place.

So, this seems really weird to pass in the same things twice. It should just be the router and transitionManager props.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, router as well – it's just that in this case, it feels more opaque to delegate everything to the matchContext prop; the affordance is that even if the user somehow directly passes in a different history or router object, that <Router> won't silently use those.

@taion
Copy link
Contributor Author

taion commented Jan 27, 2016

@timdorr What do you want to do with matchContext.history?

@timdorr
Copy link
Member

timdorr commented Jan 27, 2016

I say drop it and use props.history. Practically speaking, no one but us is going to use this for a while, so I wouldn't expect a conflicting history to be a common problem. I'll take responsibility for the tickets that crop up if I'm wrong 😆

@taion
Copy link
Contributor Author

taion commented Jan 27, 2016

How much do you care about this? I actually still think matchContext.history is cleaner here given the specifics of how this is getting used.

@timdorr
Copy link
Member

timdorr commented Jan 27, 2016

On a scale of 1 to 10: banana.

Which is to say I do not.

@taion
Copy link
Contributor Author

taion commented Jan 27, 2016

I care a little bit – makes the code in Router.js a bit cleaner. You okay with merging as-is then?

@timdorr
Copy link
Member

timdorr commented Jan 27, 2016

Yeah, let's do it.

timdorr added a commit that referenced this pull request Jan 27, 2016
…tate

Fix initial routing state after match
@timdorr timdorr merged commit c0222f2 into remix-run:master Jan 27, 2016
@taion taion deleted the createTransitionManager-initial-state branch February 3, 2016 22:11
@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

Successfully merging this pull request may close these issues.

2 participants