Skip to content

Instantly share code, notes, and snippets.

@aksel
Created December 1, 2017 09:20
Show Gist options
  • Save aksel/afb81f22ce44efc90a575470ad220a2d to your computer and use it in GitHub Desktop.
Save aksel/afb81f22ce44efc90a575470ad220a2d to your computer and use it in GitHub Desktop.
Util function that recursively traverses routes, finding the component of a route.
const SomeComponent = () => <span>Hello world</span>
export default [
{
path: '/',
name: 'main',
component: SomeComponent,
},
{
path: '/parent',
name: 'parent',
component: SomeComponent,
children: [
{
path: '/child',
name: 'child',
component: SomeComponent,
},
{
path: '/otherChild',
name: 'otherChild',
component: SomeComponent,
},
{
path: '/childWithChild',
name: 'childWithChild',
component: SomeComponent,
children: [
{
path: '/grandchild',
name: 'grandChild',
component: SomeComponent,
},
],
},
],
},
];
// Inspired by https://github.com/LeonardoGentile/react-mobx-router5/blob/master/src/modules/utils.js#L26
// It really helped me with figuring out the way router5 works.
import { startsWithSegment } from 'router5-helpers';
import allRoutes from './routes';
// Recursively traverse routes, until route matching segment is found.
// Throws error if none is found.
export const getRoute = (segment, routes) => {
for (let i = 0; i < routes.length; i += 1) {
const route = routes[i];
if (route.name === segment) {
return route;
}
// Segment is child route of current route.
if (startsWithSegment(segment, route.name) && route.children) {
const splitSegment = segment.split('.');
splitSegment.shift();
if (splitSegment.length > 0) {
return getRoute(splitSegment.join('.'), route.children);
}
}
}
throw new Error('route not found');
};
/**
* Using getRoute, finds component of route.
* Supplying a route name will find a child route of node with given name.
* E.g.:
* getComponent('parent', '') => parent
* getComponent('parent.child', 'parent') => child
* getComponent('parent.childWithChild.grandchild', 'parent.childWithChild') => grandchild
* @param name Current route name, childroutes separated with dots (e.g. parent.child)
* @param nodeName The node from which to select from. If set, will find child route of node with name.
* @returns Component (if exists), otherwise null.
*/
export function getComponent(name, nodeName = '') {
const segments = name.split('.'); // Break route in segments (levels)
const nodeSegments = nodeName.split('.');
const depth = nodeName === ''
? 1
: nodeSegments.length + 1;
const segment = segments.slice(0, depth).join('.');
const route = getRoute(segment, allRoutes);
return route.component || null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment