Implement change request in #653 (#1105)

* Implement getPathAndParamsForState for StackRouter

* Add test to make sure `params` is correct in getPathAndParamsForState of StackRouter

* chore: fix flow
This commit is contained in:
Tuyen Nguyen
2017-04-27 04:45:04 +07:00
parent 7a61cbbba2
commit 346a69f416
2 changed files with 64 additions and 5 deletions

View File

@@ -61,7 +61,7 @@ export default (
routeNames.forEach((routeName: string) => {
let pathPattern = paths[routeName] || routeConfigs[routeName].path;
const matchExact = !!pathPattern && !childRouters[routeName];
if (!pathPattern) {
if (typeof pathPattern !== 'string') {
pathPattern = routeName;
}
const keys = [];
@@ -71,7 +71,7 @@ export default (
re = new RegExp(`(?:${re.source})|(?:${wildcardRe.source})`);
}
/* $FlowFixMe */
paths[routeName] = { re, keys };
paths[routeName] = { re, keys, toPath: pathToRegexp.compile(pathPattern) };
});
return {
@@ -294,10 +294,26 @@ export default (
return state;
},
getPathAndParamsForState(): { path: string, params?: NavigationParams } {
// TODO: implement this!
getPathAndParamsForState(
state: NavigationState,
): { path: string, params?: NavigationParams } {
const route = state.routes[state.index];
const routeName = route.routeName;
const screen = getScreenForRouteName(routeConfigs, routeName);
/* $FlowFixMe */
const subPath = paths[routeName].toPath(route.params);
let path = subPath;
let params = route.params;
if (screen && screen.router) {
// If it has a router it's a navigator.
// If it doesn't have router it's an ordinary React component.
const child = screen.router.getPathAndParamsForState(route);
path = subPath ? `${subPath}/${child.path}` : child.path;
params = child.params ? { ...params, ...child.params } : params;
}
return {
path: '',
path,
params,
};
},

View File

@@ -821,6 +821,49 @@ describe('StackRouter', () => {
expect(state && state.routes[0]).toEqual({ key: 'Init', routeName: 'Bar' });
});
test('Gets deep path', () => {
const ScreenA = () => <div />;
const ScreenB = () => <div />;
ScreenA.router = StackRouter({
Boo: { path: 'boo', screen: ScreenB },
Baz: { path: 'baz/:bazId', screen: ScreenB },
});
const router = StackRouter({
Foo: {
path: 'f/:id',
screen: ScreenA,
},
Bar: {
screen: ScreenB,
},
});
const state = {
index: 0,
routes: [
{
index: 1,
key: 'Foo',
routeName: 'Foo',
params: {
id: '123',
},
routes: [
{ key: 'Boo', routeName: 'Boo' },
{ key: 'Baz', routeName: 'Baz', params: { bazId: '321' } },
],
},
{ key: 'Bar', routeName: 'Bar' },
],
};
const { path, params } = router.getPathAndParamsForState(state);
expect(path).toEqual('f/123/baz/321');
/* $FlowFixMe: params.id has to exist */
expect(params.id).toEqual('123');
/* $FlowFixMe: params.bazId has to exist */
expect(params.bazId).toEqual('321');
});
test('Maps old actions (uses "Handles the reset action" test)', () => {
const router = StackRouter({
Foo: {