taion / use-named-routes

[No Maintenance Intended] Drop-in named route support for React Router
MIT License
105 stars 8 forks source link

Docs about server side usage? #7

Open th0r opened 8 years ago

th0r commented 8 years ago

At first, thanks a lot for a great work, man!

Works like a charm but it took me a while to make it work server side with match() and I just want to share my solution here:

// app.server.js
import { match } from 'react-router';
import routes from './routes';
import createServerHistory from './createServerHistory';

// ...
match(
  { routes, history: createServerHistory(), location: req.url },
  function (error, redirectLocation, renderProps) { ... }
);
// createServerHistory.js
import { createMemoryHistory } from 'history';
import useNamedRoutes from 'use-named-routes';

import routes from './routes';

export default function createServerHistory() {
  return useNamedRoutes(createMemoryHistory)({ routes });
}

Maybe add docs about it to readme?

The only thing I don't like here is necessity to create new server history per request. This is because the underlying memory history created by createMemoryHistory is stateful but there is no need for this on server.

Do you know maybe someone has already created some kind of stateless createServerHistory and open sourced it?

taion commented 8 years ago

Drat, I knew I forgot something!

This is mostly right. A few caveats:

I'll look into setting up support (for the cached route map to avoid rebuilding it on every request) and docs, but probably not until the weekend.

th0r commented 8 years ago

You should just use createMemoryHistory from React Router, instead of both the history version and useRouterHistory

Ah, right! Haven't noticed that createMemoryHistory already contains useBasename and useQueries. Updated main post.

match() creates a memory history no matter what

The line you pointed to creates memory history only if history is not provided in the options object. Otherwise it would be impossible to add useNamedRoutes middleware and <Link> components wouldn't work.

taion commented 8 years ago

Right, so either you create one per request or match will. Either way you get a new history per request. You might be able to reuse a history across requests but I wouldn't recommend it.

th0r commented 8 years ago

You might be able to reuse a history across requests but I wouldn't recommend it.

Why? What can go wrong if it'll be stateless? It will just be used to match urls and create location objects.

taion commented 8 years ago

It's probably okay but I'm not 100% sure, and we don't document the pattern anyway.

But either way that's orthogonal, right? If you're just using match({ location, routes }) and not using this package, you are creating a new history per request.

That part doesn't change with this package; you just move the history creation into your own code.

oyeanuj commented 8 years ago

@th0r What was your final solution here for setting it up on server-side? Following what you have above gives me the following error.

TypeError: history.listen is not a function

It seems that createServerHistory.listen is not a function..

Any thoughts/insights or your final solution would be most helpful!

th0r commented 8 years ago

It seems that createServerHistory.listen is not a function

Seems like you're not callingcreateServerHistory but using it as-is. And another question: what is the history version you use? This snippet is not tested with v3, only v2.