Skip to content

Instantly share code, notes, and snippets.

@acdlite
Last active November 4, 2018 15:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save acdlite/26628a2b3b7bdc76f805 to your computer and use it in GitHub Desktop.
Save acdlite/26628a2b3b7bdc76f805 to your computer and use it in GitHub Desktop.
Minimal router using existing React Router primitives
const history = createHistory();
const router = createReactRouter(routes);
history.listen((location => {
router.match(location, (err, state, redirectInfo) => {
// Integrate with external state library (Redux), or render directly
React.render(
<RouterComponent {...state} />;
);
});
});
// On the server, just omit history
router.match(createLocation(path), (err, state, redirectInfo) => {
React.renderToString(
<RouterComponent {...state} />;
);
});
/**
* type RouterState = {
* activeRoutes: Array<Route>,
* params: Object
* }
*/
import matchRoutes from './matchRoutes';
import runTransitionHooks from './runTransitionHooks';
/**
* Base createRouter() function with no React-specific functionality,
* because #modularity
*/
export function createRouter(routes) {
let state;
function match(location, callback) {
matchRoutes(routes, location, (error, nextState) => {
if (!error) {
state = nextState;
}
callback(error, nextState);
});
}
function getState() {
return state;
}
return {
match,
getState
};
}
/**
* Router enhancer runs transition hooks when matching
*/
export function useTransitionHooks(next) {
return routes => {
const router = next(routes);
function match(location, callback) {
const prevState = router.getState();
router.match(location, (error, nextState) => {
if (error || nextState == null) {
callback(error, null);
return;
}
runTransitionHooks(prevState, nextState, (transitionError, redirectInfo) => {
if (error || redirectInfo) {
callback(error, null, redirectInfo);
}
callback(null, nextState);
});
});
}
return {
...router,
match
};
};
}
/**
* Router-creating function with transition hook functionality added
*/
export const createReactRouter = useTransitionHooks(createRouter);
@acdlite
Copy link
Author

acdlite commented Aug 17, 2015

Oh but you're right that useTransitionHooks() is a better name for that function. Nothing React-y about it.

@acdlite
Copy link
Author

acdlite commented Aug 17, 2015

And yeah I think with an API like this there's potential for a really nice middleware ecosystem, a la Redux.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment