Skip to content

Instantly share code, notes, and snippets.

@confiks
Last active September 30, 2015 21:04
Show Gist options
  • Save confiks/f6319df35d1dc2aecd86 to your computer and use it in GitHub Desktop.
Save confiks/f6319df35d1dc2aecd86 to your computer and use it in GitHub Desktop.
A quick'n'dirty 'solution' to use named routes with react-router v1.0.0-rc1
// App.js
// Route definition and lookup creation
let routes = (
<Route path="/" name="root" component={ .. }>
<Route name="customer" path="klant" component={ .. } />
..
</Route>
);
let createRouteLookupByName = (route, prefix = route.props.path) => {
let lookup = {};
React.Children.forEach(route.props.children, (child) =>
lookup = {...lookup, ...createRouteLookupByName(child, prefix + (prefix.slice(-1) === '/' ? '' : '/') + child.props.path)}
);
if(routes.type.displayName === 'Route' && route.props.name)
lookup[route.props.name] = prefix;
return lookup;
};
// A route name lookup is created, and dirtily added to the history context
let history = createBrowserHistory();
history.routeLookupByName = createRouteLookupByName(routes);
let createRouter = () => <Router history={history}>{routes}</Router>;
React.render(createRouter(), document.getElementById(..));
// --------
// Helpers.js
// Define helpers to interpolate routes and do transitioning
// _.reduce is used from lodash
export const interpolateRoute = (history, name, params = {}) => {
let path = history.routeLookupByName[name];
if(!path) {
console.warn("Route name not found:", name);
return;
}
return _.reduce(params, (path, paramV, paramK) => {
if(path.indexOf(":" + paramK) === -1)
console.warn("Route param ${paramK} not found in route name ${name}.");
return path.replace(":" + paramK, paramV);
}, path);
}
export const transitionTo = (history, name, params = {}, query = '') => {
let pathWithParams = interpolateRoute(history, name, params);
history.pushState(null, pathWithParams, query);
};
// --------
// Link.js
// Define a Link component that accepts a named route rather than a path
import { Link as ReactRouterLink } from 'react-router';
export default class extends React.Component {
static contextTypes = {
history: React.PropTypes.object.isRequired
}
static propTypes = {
to: React.PropTypes.string.isRequired,
params: React.PropTypes.object
}
render = () => {
let {to, params, ...otherProps} = this.props;
let path = Helpers.interpolateRoute(this.context.history, to, params);
return (
<ReactRouterLink {...otherProps} to={path}>
{this.props.children}
</ReactRouterLink>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment