Merge action params into navigator's child screens (#306)

This commit is contained in:
James Isaac 2017-02-20 21:59:46 +00:00 committed by Satyajit Sahoo
parent 2d0a7fa4ed
commit 15caee76f3
5 changed files with 112 additions and 2 deletions

View File

@ -247,6 +247,7 @@ export type NavigationSetParamsAction = {
export type NavigationInitAction = {
type: 'Navigation/INIT',
params?: NavigationParams,
};
export type NavigationResetAction = {

View File

@ -113,10 +113,15 @@ export default (
params: initialRouteParams,
}));
}
const params = (route.params || action.params) && {
...(route.params || {}),
...(action.params || {}),
};
route = {
...route,
routeName: initialRouteName,
key: 'Init',
...(params ? { params } : {}),
};
state = {
index: 0,
@ -139,9 +144,10 @@ export default (
const childRouter = childRouters[action.routeName];
let route;
if (childRouter) {
const childAction = action.action || NavigationActions.init({ params: action.params });
route = {
...action,
...childRouter.getStateForAction(action.action || NavigationActions.init()),
...childRouter.getStateForAction(childAction),
key: _getUuid(),
routeName: action.routeName,
};

View File

@ -60,8 +60,11 @@ export default (
const routes = order.map((routeName: string) => {
const tabRouter = tabRouters[routeName];
if (tabRouter) {
const childAction = action.action || NavigationActions.init({
...(action.params ? { params: action.params } : {}),
});
return {
...tabRouter.getStateForAction(action.action || NavigationActions.init()),
...tabRouter.getStateForAction(childAction),
key: routeName,
routeName,
};
@ -78,6 +81,20 @@ export default (
// console.log(`${order.join('-')}: Initial state`, {state});
}
if (action.type === NavigationActions.INIT) {
// Merge any params from the action into all the child routes
const { params } = action;
if (params) {
state.routes = state.routes.map(route => ({
...route,
params: {
...route.params,
...params,
}
}));
}
}
// Let the current tab handle it
const activeTabLastState = state.routes[state.index];
const activeTabRouter = tabRouters[order[state.index]];

View File

@ -468,6 +468,56 @@ describe('StackRouter', () => {
expect(state2 && state2.routes[0].routes[0].routeName).toEqual('baz');
});
test('Handles the navigate action with params and nested StackRouter', () => {
const ChildNavigator = () => <div />;
ChildNavigator.router = StackRouter({ Baz: { screen: () => <div /> } });
const router = StackRouter({
Foo: { screen: () => <div />, },
Bar: { screen: ChildNavigator, },
});
const state = router.getStateForAction({ type: NavigationActions.INIT });
const state2 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar', params: { foo: '42' } }, state);
expect(state2 && state2.routes[1].params).toEqual({ foo: '42' });
/* $FlowFixMe */
expect(state2 && state2.routes[1].routes).toEqual([
{
key: 'Init',
routeName: 'Baz',
params: { foo: '42' },
},
]);
});
test('Handles the navigate action with params and nested TabRouter', () => {
const ChildNavigator = () => <div />;
ChildNavigator.router = TabRouter({
Baz: { screen: () => <div /> },
Boo: { screen: () => <div /> },
});
const router = StackRouter({
Foo: { screen: () => <div />, },
Bar: { screen: ChildNavigator, },
});
const state = router.getStateForAction({ type: NavigationActions.INIT });
const state2 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar', params: { foo: '42' } }, state);
expect(state2 && state2.routes[1].params).toEqual({ foo: '42' });
/* $FlowFixMe */
expect(state2 && state2.routes[1].routes).toEqual([
{
key: 'Baz',
routeName: 'Baz',
params: { foo: '42' },
},
{
key: 'Boo',
routeName: 'Boo',
params: { foo: '42' },
},
]);
});
test('Handles empty URIs', () => {
const router = StackRouter({
Foo: {

View File

@ -139,6 +139,42 @@ describe('TabRouter', () => {
});
});
test('Handles passing params to nested tabs', () => {
const ChildTabNavigator = () => <div />;
ChildTabNavigator.router = TabRouter({ Boo: BareLeafRouteConfig, Bar: BareLeafRouteConfig });
const router = TabRouter({ Foo: BareLeafRouteConfig, Baz: { screen: ChildTabNavigator } });
const navAction = { type: NavigationActions.NAVIGATE, routeName: 'Baz', params: { foo: '42', bar: '43' } };
let state = router.getStateForAction(navAction);
expect(state).toEqual({
index: 1,
routes: [
{ key: 'Foo', routeName: 'Foo' },
{
index: 0,
key: 'Baz',
routeName: 'Baz',
routes: [
{ key: 'Boo', routeName: 'Boo', params: { foo: '42', bar: '43' } },
{ key: 'Bar', routeName: 'Bar', params: { foo: '42', bar: '43' } },
],
},
],
});
// Ensure that navigating back and forth doesn't overwrite
state = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar' }, state);
state = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Boo' }, state);
expect(state && state.routes[1]).toEqual({
index: 0,
key: 'Baz',
routeName: 'Baz',
routes: [
{ key: 'Boo', routeName: 'Boo', params: { foo: '42', bar: '43' } },
{ key: 'Bar', routeName: 'Bar', params: { foo: '42', bar: '43' } },
],
});
});
test('Handles initial deep linking into nested tabs', () => {
const ChildTabNavigator = () => <div />;
ChildTabNavigator.router = TabRouter({ Foo: BareLeafRouteConfig, Bar: BareLeafRouteConfig });