Use redux constants and action creator functions (#120)

This commit is contained in:
Jeff Carbonella
2017-02-01 16:27:51 -05:00
parent d677e6d45e
commit b33c0ae133
25 changed files with 317 additions and 164 deletions

View File

@@ -78,7 +78,7 @@ const MyAppRouter = {
getStateForAction(action, state) {
if (
state &&
action.type === 'Back' &&
action.type === NavigationActions.BACK &&
state.routes[state.index].params.isEditing
) {
// Returning null from getStateForAction means that the action
@@ -97,6 +97,8 @@ Perhaps your app has a unique URI which the built-in routers cannot handle. You
```js
import { NavigationActions } from 'react-navigation'
const MyApp = StackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
@@ -111,17 +113,15 @@ MyApp.router = {
params.magic === 'yes'
) {
// returns a profile navigate action for /my/custom/path?magic=yes
return {
type: 'Navigate',
return NavigationActions.navigate({
routeName: 'Profile',
action: {
action: NavigationActions.navigate({
// This child action will get passed to the child router
// ProfileScreen.router.getStateForAction to get the child
// navigation state.
type: 'Navigate',
routeName: 'Friends',
},
};
}),
});
return null;
}
return MyApp.router.getStateForAction(action, state);

View File

@@ -56,8 +56,8 @@ A navigation-aware component that hosts other navigation-aware components. Most
The navigation prop should be provided to components who need access to navigation. If provided, it must follow this interface:
```javascript
type BackAction = {type: 'Back'};
type URIAction = {type: 'URI', uri: string};
type BackAction = {type: 'Navigation/BACK'};
type URIAction = {type: 'Navigation/URI', uri: string};
interface Navigation<S, A> {
dispatch(action: (A | BackAction | URIAction)): boolean;
@@ -81,7 +81,7 @@ const MyView = ({ navigation }) => {
#### navigation.dispatch(action)
The channel that a component can call to request navigation from its parent. When calling `dispatch`, you must provide an action object with a `type`. There are two special action types: 'Back' and 'URI'.
The channel that a component can call to request navigation from its parent. When calling `dispatch`, you must provide an action object with a `type`. There are two special action types: 'Navigation/BACK' and 'Navigation/URI'.
```javascript
const MyLink = ({ navigation }) => (
@@ -102,8 +102,8 @@ const MyLink = ({ navigation }) => (
A router object may be statically defined on your component. If defined, it must follow this interface:
```javascript
type BackAction = {type: 'Back'};
type URIAction = {type: 'URI', uri: string};
type BackAction = {type: 'Navigation/BACK'};
type URIAction = {type: 'Navigation/URI', uri: string};
interface Router<S, A> {
getStateForAction(action: (A | BackAction | URIAction), lastState: ?S): ?S;
@@ -151,7 +151,7 @@ There are two special actions that can be fired into `navigation.dispatch` and c
This action means the same thing as an Android back button press.
```
type BackAction = { type: 'Back' };
type BackAction = { type: 'Navigation/BACK' };
```
#### URI Open Action
@@ -159,7 +159,7 @@ type BackAction = { type: 'Back' };
Used to request the enclosing app or OS to open a link at a particular URI. If it is a web URI like `http` or `https`, the app may open a WebView to present the page. Or the app may open the URI in a web browser. In some cases, an app may choose to block a URI action or handle it differently.
```
type URIAction = { type: 'URI', uri: string };
type URIAction = { type: 'Navigation/URI', uri: string };
```
@@ -186,7 +186,7 @@ To block the Android back button:
class Foo extends React.Component {
static router = {
getStateForAction(action, prevState = {}) {
if (action.type === 'Back') return null;
if (action.type === 'Navigation/BACK') return null;
else return prevState;
},
};

View File

@@ -19,7 +19,7 @@ class MyNavigationAwareComponent extends React.Component {
const state = lastState = { myMode: 'default' };
if (action.type === 'MyAction') {
return { myMode: 'action' };
} else if (action.type === 'Back') {
} else if (action.type === NavigationActions.BACK) {
return { myMode: 'blockBackButton' };
} else {
return state;

View File

@@ -79,7 +79,7 @@ class InfraScreen extends React.Component {
HybridNavigationModule.openURI(action.uri);
return true;
}
if (action.type === 'Back') {
if (action.type === NavigationActions.BACK) {
HybridNavigationModule.goBack();
return true;
}

View File

@@ -102,18 +102,21 @@ Optionally provide a key, which specifies the route to go back from. By default,
Use dispatch to send any navigation action to the router. The other navigation functions use dispatch behind the scenes.
Note that if you want to dispatch react-navigation actions you should use the action creators provided in this library.
The following actions are supported:
### Navigate
```js
{
type: 'Navigate',
import { NavigationActions } from 'react-navigation'
NavigationActions.navigate({
routeName: 'Profile',
params: {},
// navigate can have a nested navigate action that will be run inside the child router
action: {type: 'Navigate', routeName: 'SubProfileRoute'}
}
action: NavigationActions.navigate({ routeName: 'SubProfileRoute'})
})
```
@@ -122,10 +125,11 @@ The following actions are supported:
The `Reset` action wipes the whole navigation state and replaces it with the result of several actions.
```js
{
type: 'Reset',
actions: ,
}
import { NavigationActions } from 'react-navigation'
NavigationActions.reset({
actions: NavigationActions.navigate({ routeName: 'Profile'}),
})
```
### SetParams
@@ -133,10 +137,11 @@ The `Reset` action wipes the whole navigation state and replaces it with the res
When dispatching `SetParams`, the router will produce a new state that has changed the params of a particular route, as identified by the key
```js
{
type: 'SetParams',
import { NavigationActions } from 'react-navigation'
NavigationActions.setParams({
params: {}, // these are the new params that will be merged into the existing route params
// The key of the route that should get the new params
key: 'screen-123',
}
})
```

View File

@@ -7,6 +7,7 @@ import {
NativeModules,
} from 'react-native';
import {
NavigationActions,
addNavigationHelpers,
} from 'react-navigation';
@@ -22,7 +23,7 @@ const HybridContainer = (ReactScreens) => {
let ScreenView = ReactScreens[name];
let screenKey = name;
let navState = null;
const action = { type: 'Navigate', routeName: name, params };
const action = NavigationActions.navigate({ routeName: name, params };
if (!ScreenView) {
// Deep linking magic here. Try each screen to see if the state changes
// in response to this action. The first screen who returns
@@ -33,7 +34,7 @@ const HybridContainer = (ReactScreens) => {
if (!V || !V.router || !V.router.getStateForAction) {
return;
}
const baseState = V.router.getStateForAction({ type: 'Init' });
const baseState = V.router.getStateForAction(NavigationActions.init());
const linkedState = V.router.getStateForAction(action, baseState);
if (baseState !== linkedState) {
ScreenView = V;
@@ -77,7 +78,7 @@ const HybridContainer = (ReactScreens) => {
this.setState({ navState });
return true;
}
if (action.type === 'Navigate') {
if (action.type === NavigationActions.NAVIGATE) {
HybridNavigationManager.navigate(action.routeName, action.params || {});
}
return true;

View File

@@ -12,6 +12,7 @@ import {
View,
} from 'react-native';
import {
NavigationActions,
addNavigationHelpers,
StackNavigator,
} from 'react-navigation';
@@ -70,7 +71,7 @@ const LoginStatusMessage = connect(state => ({
{'You are "logged in" right now'}
</Text>
<Button
onPress={() => dispatch({ type: 'Navigate', routeName: 'Profile' })}
onPress={() => dispatch(NavigationActions.navigate({ routeName: 'Profile' }))}
title="Profile"
/>
</View>
@@ -81,7 +82,7 @@ const AuthButton = connect(state => ({
isLoggedIn: state.auth.isLoggedIn,
}), dispatch => ({
logout: () => dispatch({ type: 'Logout' }),
login: () => dispatch({ type: 'Navigate', routeName: 'Login' }),
login: () => dispatch(NavigationActions.navigate({ routeName: 'Login' })),
}))(({ logout, login, isLoggedIn }) => (
<Button
title={isLoggedIn ? 'Log Out' : 'Log In'}
@@ -124,10 +125,10 @@ const initialAuthState = { isLoggedIn: false };
const AppReducer = combineReducers({
nav: (state = initialNavState, action) => {
if (action.type === 'Login') {
return AppNavigator.router.getStateForAction({ type: 'Back' }, state);
return AppNavigator.router.getStateForAction(NavigationActions.back(), state);
}
if (action.type === 'Logout') {
return AppNavigator.router.getStateForAction({ type: 'Navigate', routeName: 'Login' }, state);
return AppNavigator.router.getStateForAction(NavigationActions.navigate({ routeName: 'Login' }), state);
}
return AppNavigator.router.getStateForAction(action, state);
},

View File

@@ -0,0 +1,70 @@
const namespacedAction = (action: string) => `Navigation/${action}`;
const BACK = namespacedAction('BACK');
const INIT = namespacedAction('INIT');
const NAVIGATE = namespacedAction('NAVIGATE');
const RESET = namespacedAction('RESET');
const SET_PARAMS = namespacedAction('SET_PARAMS');
const URI = namespacedAction('URI');
const createAction = (type: string) => (payload: object = {}) => ({
type,
...payload,
});
const back = createAction(BACK);
const init = createAction(INIT);
const navigate = createAction(NAVIGATE);
const reset = createAction(RESET);
const setParams = createAction(SET_PARAMS);
const uri = createAction(URI);
const deprecatedActionMap = {
Back: BACK,
Init: INIT,
Navigate: NAVIGATE,
Reset: RESET,
SetParams: SET_PARAMS,
Uri: URI,
};
const mapDeprecatedActionAndWarn = (action: object) => {
const mappedType = deprecatedActionMap[action.type];
if (!mappedType) { return action; }
console.warn([
`The action type '${action.type}' has been renamed to '${mappedType}'.`,
`'${action.type}' will continue to work while in beta but will be removed`,
'in the first major release. Moving forward, you should use the',
'action constants and action creators exported by this library in',
"the 'actions' object.",
'See https://github.com/react-community/react-navigation/pull/120 for',
'more details.',
].join(' '));
return {
...action,
type: deprecatedActionMap[action.type],
};
};
export default {
// Action constants
BACK,
INIT,
NAVIGATE,
RESET,
SET_PARAMS,
URI,
// Action creators
back,
init,
navigate,
reset,
setParams,
uri,
// TODO: Remove once old actions are deprecated
mapDeprecatedActionAndWarn,
};

View File

@@ -203,7 +203,7 @@ export type NavigationParams = {
};
export type NavigationNavigateAction = {
type: 'Navigate',
type: 'Navigation/NAVIGATE',
routeName: string,
params?: NavigationParams,
@@ -212,12 +212,12 @@ export type NavigationNavigateAction = {
};
export type NavigationBackAction = {
type: 'Back',
type: 'Navigation/BACK',
key?: ?string,
};
export type NavigationSetParamsAction = {
type: 'SetParams',
type: 'Navigation/SET_PARAMS',
// The key of the route where the params should be set
key: string,
@@ -227,15 +227,20 @@ export type NavigationSetParamsAction = {
};
export type NavigationInitAction = {
type: 'Init',
type: 'Navigation/INIT',
};
export type NavigationResetAction = {
type: 'Reset',
type: 'Navigation/RESET',
index: number,
actions: Array<NavigationNavigateAction>,
};
export type NavigationUriAction = {
type: 'Navigation/URI',
uri: string,
};
export type NavigationContainerOptions = {
// This is used to extract the path from the URI passed to the app for a deep link
URIPrefix?: string,
@@ -302,7 +307,7 @@ export type NavigationTabRouterConfig = {
paths?: NavigationPathsConfig,
navigationOptions?: NavigationScreenOptions,
order?: Array<string>, // todo: type these as the real route names rather than 'string'
// Does the back button cause the router to switch to the initial tab
backBehavior?: 'none' | 'initialRoute', // defaults `initialRoute`
};

View File

@@ -0,0 +1,37 @@
/* @flow */
import NavigationActions from '../NavigationActions';
describe('actions', () => {
const data = { foo: 'bar' };
it('exports back action and type', () => {
expect(NavigationActions.back()).toEqual({ type: NavigationActions.BACK });
expect(NavigationActions.back(data)).toEqual({ type: NavigationActions.BACK, ...data });
});
it('exports init action and type', () => {
expect(NavigationActions.init()).toEqual({ type: NavigationActions.INIT });
expect(NavigationActions.init(data)).toEqual({ type: NavigationActions.INIT, ...data });
});
it('exports navigate action and type', () => {
expect(NavigationActions.navigate()).toEqual({ type: NavigationActions.NAVIGATE });
expect(NavigationActions.navigate(data)).toEqual({ type: NavigationActions.NAVIGATE, ...data });
});
it('exports reset action and type', () => {
expect(NavigationActions.reset()).toEqual({ type: NavigationActions.RESET });
expect(NavigationActions.reset(data)).toEqual({ type: NavigationActions.RESET, ...data });
});
it('exports setParams action and type', () => {
expect(NavigationActions.setParams()).toEqual({ type: NavigationActions.SET_PARAMS });
expect(NavigationActions.setParams(data)).toEqual({ type: NavigationActions.SET_PARAMS, ...data });
});
it('exports uri action and type', () => {
expect(NavigationActions.uri()).toEqual({ type: NavigationActions.URI });
expect(NavigationActions.uri(data)).toEqual({ type: NavigationActions.URI, ...data });
});
});

View File

@@ -1,5 +1,6 @@
/* @flow */
import NavigationActions from '../NavigationActions';
import addNavigationHelpers from '../addNavigationHelpers';
describe('addNavigationHelpers', () => {
@@ -9,7 +10,7 @@ describe('addNavigationHelpers', () => {
state: { key: 'A', routeName: 'Home' },
dispatch: mockedDispatch,
}).goBack('A')).toEqual(true);
expect(mockedDispatch).toBeCalledWith({ type: 'Back', key: 'A' });
expect(mockedDispatch).toBeCalledWith({ type: NavigationActions.BACK, key: 'A' });
expect(mockedDispatch.mock.calls.length).toBe(1);
});
@@ -19,7 +20,7 @@ describe('addNavigationHelpers', () => {
state: {},
dispatch: mockedDispatch,
}).goBack()).toEqual(true);
expect(mockedDispatch).toBeCalledWith({ type: 'Back' });
expect(mockedDispatch).toBeCalledWith({ type: NavigationActions.BACK });
expect(mockedDispatch.mock.calls.length).toBe(1);
});
@@ -30,7 +31,7 @@ describe('addNavigationHelpers', () => {
dispatch: mockedDispatch,
}).navigate('Profile', { name: 'Matt' })).toEqual(true);
expect(mockedDispatch).toBeCalledWith({
type: 'Navigate',
type: NavigationActions.NAVIGATE,
params: { name: 'Matt' },
routeName: 'Profile',
});
@@ -44,7 +45,7 @@ describe('addNavigationHelpers', () => {
dispatch: mockedDispatch,
}).setParams({ notificationsEnabled: true })).toEqual(true);
expect(mockedDispatch).toBeCalledWith({
type: 'SetParams',
type: NavigationActions.SET_PARAMS,
key: 'B',
params: { notificationsEnabled: true },
});

View File

@@ -11,26 +11,31 @@ import type {
NavigationRoute,
} from './TypeDefinition';
import NavigationActions from './NavigationActions'
export default (navigation: NavigationProp<NavigationRoute, NavigationAction>): NavigationScreenProp<NavigationRoute, NavigationAction> => ({
...navigation,
goBack: (key): boolean => {
return navigation.dispatch({
type: 'Back',
return navigation.dispatch(NavigationActions.back({
key: key === undefined ? navigation.state.key : key,
});
}));
},
navigate: (routeName, params, action): boolean => {
return navigation.dispatch({
type: 'Navigate',
return navigation.dispatch(NavigationActions.navigate({
routeName,
params,
action,
});
}));
},
/**
* For updating current route params. For example the nav bar title and
* buttons are based on the route params.
* This means `setParams` can be used to update nav bar for example.
*/
setParams: params => navigation.dispatch({ type: 'SetParams', params, key: navigation.state.key }),
setParams: (params): boolean => {
return navigation.dispatch(NavigationActions.setParams({
params,
key: navigation.state.key
}));
}
});

View File

@@ -6,6 +6,7 @@ import {
Linking,
} from 'react-native';
import invariant from 'fbjs/lib/invariant';
import NavigationActions from './NavigationActions';
import addNavigationHelpers from './addNavigationHelpers';
import type {
@@ -77,7 +78,7 @@ const createNavigationContainer = (
this.state = null;
if (this._isStateful()) {
this.state = {
nav: Component.router.getStateForAction({ type: 'Init' }),
nav: Component.router.getStateForAction(NavigationActions.init()),
};
}
}
@@ -85,7 +86,7 @@ const createNavigationContainer = (
componentDidMount() {
if (this._isStateful()) {
this.subs = BackAndroid.addEventListener('backPress', () =>
this.dispatch({ type: 'Back' })
this.dispatch(NavigationActions.back())
);
Linking.addEventListener('url', this._handleOpenURL);
Linking.getInitialURL().then((url: string) => {

View File

@@ -9,6 +9,7 @@ module.exports = {
get StateUtils() { return require('./StateUtils').default; },
get PropTypes() { return require('./PropTypes').default; },
get addNavigationHelpers() { return require('./addNavigationHelpers').default; },
get NavigationActions() { return require('./NavigationActions').default; },
// Navigators
get createNavigator() { return require('./navigators/createNavigator').default; },

View File

@@ -9,6 +9,7 @@ module.exports = {
get StateUtils() { return require('./StateUtils').default; },
get PropTypes() { return require('./PropTypes').default; },
get addNavigationHelpers() { return require('./addNavigationHelpers').default; },
get NavigationActions() { return require('./NavigationActions').default; },
// Navigators
get createNavigator() { return require('./navigators/createNavigator').default; },

View File

@@ -2,6 +2,7 @@
import pathToRegexp from 'path-to-regexp';
import NavigationActions from '../NavigationActions';
import createConfigGetter from './createConfigGetter';
import getScreenForRouteName from './getScreenForRouteName';
import StateUtils from '../StateUtils';
@@ -90,10 +91,12 @@ export default (
},
getStateForAction(action: NavigationStackAction, state: ?NavigationState) {
action = NavigationActions.mapDeprecatedActionAndWarn(action)
// Set up the initial state if needed
if (!state) {
let route = {};
if (action.type === 'Navigate' && (childRouters[action.routeName] !== undefined)) {
if (action.type === NavigationActions.NAVIGATE && (childRouters[action.routeName] !== undefined)) {
return {
index: 0,
routes: [
@@ -106,11 +109,10 @@ export default (
};
}
if (initialChildRouter) {
route = initialChildRouter.getStateForAction({
type: 'Navigate',
route = initialChildRouter.getStateForAction(NavigationActions.navigate({
routeName: initialRouteName,
params: initialRouteParams,
});
}));
}
route = {
...route,
@@ -134,13 +136,13 @@ export default (
}
// Handle push/pop
if (action.type === 'Navigate' && childRouters[action.routeName] !== undefined) {
if (action.type === NavigationActions.NAVIGATE && childRouters[action.routeName] !== undefined) {
const childRouter = childRouters[action.routeName];
let route;
if (childRouter) {
route = {
...action,
...childRouter.getStateForAction(action.action || { type: 'Init' }),
...childRouter.getStateForAction(action.action || NavigationActions.init()),
key: _getUuid(),
routeName: action.routeName,
};
@@ -154,7 +156,7 @@ export default (
return StateUtils.push(state, route);
}
if (action.type === 'SetParams') {
if (action.type === NavigationActions.SET_PARAMS) {
const lastRoute = state.routes.find(route => route.key === action.key);
if (lastRoute) {
const params = {
@@ -173,7 +175,7 @@ export default (
}
}
if (action.type === 'Reset') {
if (action.type === NavigationActions.RESET) {
const resetAction = ((action: any): NavigationResetAction);
return {
@@ -199,7 +201,7 @@ export default (
};
}
if (action.type === 'Back') {
if (action.type === NavigationActions.BACK) {
let backRouteIndex = null;
if (action.key) {
const backRoute = state.routes.find(route => route.key === action.key);
@@ -230,10 +232,9 @@ export default (
// If the path is empty (null or empty string)
// just return the initial route action
if (!pathToResolve) {
return {
type: 'Navigate',
return NavigationActions.navigate({
routeName: initialRouteName,
};
});
}
// Attempt to match `pathToResolve` with a route in this router's
@@ -280,12 +281,11 @@ export default (
return result;
}, null);
return {
type: 'Navigate',
return NavigationActions.navigate({
routeName: matchedRouteName,
...(params ? { params } : {}),
...(nestedAction ? { action: nestedAction } : {}),
};
});
},
getScreenConfig: createConfigGetter(routeConfigs, stackConfig.navigationOptions),

View File

@@ -7,6 +7,7 @@ import createConfigGetter from './createConfigGetter';
import invariant from 'fbjs/lib/invariant';
import warning from 'fbjs/lib/warning';
import NavigationActions from '../NavigationActions';
import StateUtils from '../StateUtils';
import validateRouteConfigMap from './validateRouteConfigMap';
@@ -22,8 +23,6 @@ import type {
NavigationTabRouterConfig,
} from '../TypeDefinition';
const INIT_ACTION = { type: 'Init' };
export default (
routeConfigs: NavigationRouteConfigMap,
config: NavigationTabRouterConfig = {}
@@ -53,6 +52,8 @@ export default (
);
return {
getStateForAction(action: NavigationAction, inputState: ?NavigationState): ?NavigationState {
action = NavigationActions.mapDeprecatedActionAndWarn(action)
// Establish a default state
let state = inputState;
if (!state) {
@@ -60,7 +61,7 @@ export default (
const tabRouter = tabRouters[routeName];
if (tabRouter) {
return {
...tabRouter.getStateForAction(action.action || INIT_ACTION),
...tabRouter.getStateForAction(action.action || NavigationActions.init()),
key: routeName,
routeName,
};
@@ -99,11 +100,11 @@ export default (
// handle the action, to allow inner tabs to change first
let activeTabIndex = state.index;
const isBackEligible = action.key == null || action.key === activeTabLastState.key;
if (action.type === 'Back' && isBackEligible && shouldBackNavigateToInitialRoute) {
if (action.type === NavigationActions.BACK && isBackEligible && shouldBackNavigateToInitialRoute) {
activeTabIndex = initialRouteIndex;
}
let didNavigate = false;
if (action.type === 'Navigate') {
if (action.type === NavigationActions.NAVIGATE) {
const navigateAction = ((action: any): NavigationNavigateAction);
didNavigate = !!order.find((tabId: string, i: number) => {
if (tabId === navigateAction.routeName) {
@@ -225,10 +226,9 @@ export default (
const pathToTest = paths[tabId];
if (parts[0] === pathToTest) {
const tabRouter = tabRouters[tabId];
const action: NavigationNavigateAction = {
type: 'Navigate',
const action: NavigationNavigateAction = NavigationActions.navigate({
routeName: tabId,
};
});
if (tabRouter && tabRouter.getActionForPathAndParams) {
action.action = tabRouter.getActionForPathAndParams(parts.slice(1).join('/'), params);
} else if (params) {

View File

@@ -7,6 +7,7 @@ import React from 'react';
import StackRouter from '../StackRouter';
import TabRouter from '../TabRouter';
import NavigationActions from '../../NavigationActions';
import addNavigationHelpers from '../../addNavigationHelpers';
const ROUTERS = {
@@ -63,10 +64,10 @@ test('Handles no-op actions with tabs within stack router', () => {
screen: BarView,
},
});
const state1 = TestRouter.getStateForAction({ type: 'Init' });
const state2 = TestRouter.getStateForAction({ type: 'Navigate', routeName: 'Qux' });
const state1 = TestRouter.getStateForAction({ type: NavigationActions.INIT });
const state2 = TestRouter.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Qux' });
expect(state1).toEqual(state2);
const state3 = TestRouter.getStateForAction({ type: 'Navigate', routeName: 'Zap' }, state2);
const state3 = TestRouter.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Zap' }, state2);
expect(state2).toEqual(state3);
});
@@ -81,7 +82,7 @@ test('Handles deep action', () => {
Bar: { screen: BarView },
Foo: { screen: FooTabNavigator },
});
const state1 = TestRouter.getStateForAction({ type: 'Init' });
const state1 = TestRouter.getStateForAction({ type: NavigationActions.INIT });
const expectedState = {
index: 0,
routes: [
@@ -92,7 +93,7 @@ test('Handles deep action', () => {
],
};
expect(state1).toEqual(expectedState);
const state2 = TestRouter.getStateForAction({ type: 'Navigate', routeName: 'Foo', action: {type: 'Navigate', routeName: 'Zoo'} }, state1);
const state2 = TestRouter.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Foo', action: {type: NavigationActions.NAVIGATE, routeName: 'Zoo'} }, state1);
expect(state2.index).toEqual(1);
expect(state2.routes[1].index).toEqual(1);
});
@@ -112,9 +113,9 @@ test('Supports lazily-evaluated getScreen', () => {
getScreen: () => BarView,
},
});
const state1 = TestRouter.getStateForAction({ type: 'Init' });
const state2 = TestRouter.getStateForAction({ type: 'Navigate', routeName: 'Qux' });
const state1 = TestRouter.getStateForAction({ type: NavigationActions.INIT });
const state2 = TestRouter.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Qux' });
expect(state1).toEqual(state2);
const state3 = TestRouter.getStateForAction({ type: 'Navigate', routeName: 'Zap' }, state2);
const state3 = TestRouter.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Zap' }, state2);
expect(state2).toEqual(state3);
});

View File

@@ -7,6 +7,8 @@ import React from 'react';
import StackRouter from '../StackRouter';
import TabRouter from '../TabRouter';
import NavigationActions from '../../NavigationActions';
const ListScreen = () => <div />;
const ProfileNavigator = () => <div />;
@@ -170,14 +172,14 @@ describe('StackRouter', () => {
test('Parses simple paths', () => {
expect(AuthNavigator.router.getActionForPathAndParams('login')).toEqual({
type: 'Navigate',
type: NavigationActions.NAVIGATE,
routeName: 'login',
});
});
test('Parses paths with a param', () => {
expect(TestStackRouter.getActionForPathAndParams('people/foo')).toEqual({
type: 'Navigate',
type: NavigationActions.NAVIGATE,
routeName: 'person',
params: {
id: 'foo',
@@ -190,10 +192,10 @@ describe('StackRouter', () => {
const uri = 'auth/login';
const action = TestStackRouter.getActionForPathAndParams(uri);
expect(action).toEqual({
type: 'Navigate',
type: NavigationActions.NAVIGATE,
routeName: 'auth',
action: {
type: 'Navigate',
type: NavigationActions.NAVIGATE,
routeName: 'login',
},
});
@@ -203,16 +205,16 @@ describe('StackRouter', () => {
const uri = 'main/p/4/list/10259959195';
const action = TestStackRouter.getActionForPathAndParams(uri);
expect(action).toEqual({
type: 'Navigate',
type: NavigationActions.NAVIGATE,
routeName: 'main',
action: {
type: 'Navigate',
type: NavigationActions.NAVIGATE,
routeName: 'profile',
params: {
id: '4',
},
action: {
type: 'Navigate',
type: NavigationActions.NAVIGATE,
routeName: 'list',
params: {
id: '10259959195',
@@ -232,10 +234,10 @@ describe('StackRouter', () => {
const uri = 'auth/login/2';
const action = TestStackRouter.getActionForPathAndParams(uri);
expect(action).toEqual({
type: 'Navigate',
type: NavigationActions.NAVIGATE,
routeName: 'auth',
action: {
type: 'Navigate',
type: NavigationActions.NAVIGATE,
routeName: 'login',
},
});
@@ -245,13 +247,13 @@ describe('StackRouter', () => {
const path = 'fo/22/b/hello';
const action = TestStackRouter.getActionForPathAndParams(path);
expect(action).toEqual({
type: 'Navigate',
type: NavigationActions.NAVIGATE,
routeName: 'foo',
params: {
fooThing: '22',
},
action: {
type: 'Navigate',
type: NavigationActions.NAVIGATE,
routeName: 'bar',
params: {
barThing: 'hello',
@@ -271,7 +273,7 @@ describe('StackRouter', () => {
screen: BarScreen,
},
});
const state = router.getStateForAction({ type: 'Init' });
const state = router.getStateForAction({ type: NavigationActions.INIT });
expect(state).toEqual({
index: 0,
routes: [
@@ -281,12 +283,12 @@ describe('StackRouter', () => {
},
],
});
const state2 = router.getStateForAction({ type: 'Navigate', routeName: 'Bar', params: { name: 'Zoom' } }, state);
const state2 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar', params: { name: 'Zoom' } }, state);
expect(state2 && state2.index).toEqual(1);
expect(state2 && state2.routes[1].routeName).toEqual('Bar');
expect(state2 && state2.routes[1].params).toEqual({ name: 'Zoom' });
expect(state2 && state2.routes.length).toEqual(2);
const state3 = router.getStateForAction({ type: 'Back' }, state2);
const state3 = router.getStateForAction({ type: NavigationActions.BACK }, state2);
expect(state3).toEqual({
index: 0,
routes: [
@@ -314,7 +316,7 @@ describe('StackRouter', () => {
screen: BarScreen,
},
});
const state = router.getStateForAction({ type: 'Init' });
const state = router.getStateForAction({ type: NavigationActions.INIT });
expect(state).toEqual({
index: 0,
routes: [
@@ -324,12 +326,12 @@ describe('StackRouter', () => {
},
],
});
const state2 = router.getStateForAction({ type: 'Navigate', routeName: 'Bar', params: { name: 'Zoom' } }, state);
const state2 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar', params: { name: 'Zoom' } }, state);
expect(state2 && state2.index).toEqual(1);
expect(state2 && state2.routes[1].routeName).toEqual('Bar');
expect(state2 && state2.routes[1].params).toEqual({ name: 'Zoom' });
expect(state2 && state2.routes.length).toEqual(2);
const state3 = router.getStateForAction({ type: 'Back' }, state2);
const state3 = router.getStateForAction({ type: NavigationActions.BACK }, state2);
expect(state3).toEqual({
index: 0,
routes: [
@@ -352,12 +354,12 @@ describe('StackRouter', () => {
screen: BarScreen,
},
});
const state = router.getStateForAction({ type: 'Init' });
const state2 = router.getStateForAction({ type: 'Navigate', routeName: 'Bar', params: { name: 'Zoom' } }, state);
const state3 = router.getStateForAction({ type: 'Navigate', routeName: 'Bar', params: { name: 'Foo' } }, state2);
const state4 = router.getStateForAction({ type: 'Back', key: 'wrongKey' }, state3);
const state = router.getStateForAction({ type: NavigationActions.INIT });
const state2 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar', params: { name: 'Zoom' } }, state);
const state3 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar', params: { name: 'Foo' } }, state2);
const state4 = router.getStateForAction({ type: NavigationActions.BACK, key: 'wrongKey' }, state3);
expect(state3).toEqual(state4);
const state5 = router.getStateForAction({ type: 'Back', key: state3.routes[1].key }, state4);
const state5 = router.getStateForAction({ type: NavigationActions.BACK, key: state3.routes[1].key }, state4);
expect(state5).toEqual(state);
});
@@ -372,7 +374,7 @@ describe('StackRouter', () => {
screen: BarScreen,
},
}, { initialRouteName: 'Bar' });
const state = router.getStateForAction({ type: 'Init' });
const state = router.getStateForAction({ type: NavigationActions.INIT });
expect(state).toEqual({
index: 0,
routes: [
@@ -395,8 +397,8 @@ describe('StackRouter', () => {
screen: BarScreen,
},
});
const state = router.getStateForAction({ type: 'Init' });
const state2 = router.getStateForAction({ type: 'Navigate', routeName: 'Bar', params: { bar: '42' } }, state);
const state = router.getStateForAction({ type: NavigationActions.INIT });
const state2 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar', params: { bar: '42' } }, state);
expect(state2).not.toBeNull();
expect(state2 && state2.index).toEqual(1);
expect(state2 && state2.routes[1].params).toEqual({ bar: '42' });
@@ -414,9 +416,9 @@ describe('StackRouter', () => {
initialRouteName: 'Bar',
initialRouteParams: { name: 'Zoo' },
});
const state = router.getStateForAction({ type: 'Init' });
const state = router.getStateForAction({ type: NavigationActions.INIT });
const state2 = router.getStateForAction({
type: 'SetParams',
type: NavigationActions.SET_PARAMS,
params: { name: 'Qux' },
key: 'Init',
}, state);
@@ -433,8 +435,8 @@ describe('StackRouter', () => {
screen: () => <div />,
},
});
const state = router.getStateForAction({ type: 'Init' });
const state2 = router.getStateForAction({ type: 'Reset', actions: [{ type: 'Navigate', routeName: 'Foo', params: { bar: '42' } }, { type: 'Navigate', routeName: 'Bar' }], index: 1 }, state);
const state = router.getStateForAction({ type: NavigationActions.INIT });
const state2 = router.getStateForAction({ type: NavigationActions.RESET, actions: [{ type: NavigationActions.NAVIGATE, routeName: 'Foo', params: { bar: '42' } }, { type: NavigationActions.NAVIGATE, routeName: 'Bar' }], index: 1 }, state);
expect(state2 && state2.index).toEqual(1);
expect(state2 && state2.routes[0].params).toEqual({ bar: '42' });
expect(state2 && state2.routes[0].routeName).toEqual('Foo');
@@ -459,8 +461,8 @@ describe('StackRouter', () => {
screen: () => <div />,
},
});
const state = router.getStateForAction({ type: 'Init' });
const state2 = router.getStateForAction({ type: 'Reset', actions: [{ type: 'Navigate', routeName: 'Foo' }], index: 0 }, state);
const state = router.getStateForAction({ type: NavigationActions.INIT });
const state2 = router.getStateForAction({ type: NavigationActions.RESET, actions: [{ type: NavigationActions.NAVIGATE, routeName: 'Foo' }], index: 0 }, state);
expect(state2 && state2.index).toEqual(0);
expect(state2 && state2.routes[0].routeName).toEqual('Foo');
@@ -477,7 +479,7 @@ describe('StackRouter', () => {
},
}, { initialRouteName: 'Bar' });
const action = router.getActionForPathAndParams('');
expect(action).toEqual({ type: 'Navigate', routeName: 'Bar' });
expect(action).toEqual({ type: NavigationActions.NAVIGATE, routeName: 'Bar' });
let state = null;
if (action) {
state = router.getStateForAction(action);
@@ -485,4 +487,21 @@ describe('StackRouter', () => {
expect(state && state.index).toEqual(0);
expect(state && state.routes[0]).toEqual({ key: 'Init', routeName: 'Bar' });
});
test('Maps old actions (uses "Handles the reset action" test)', () => {
const router = StackRouter({
Foo: {
screen: () => <div />,
},
Bar: {
screen: () => <div />,
},
});
const state = router.getStateForAction({ type: 'Init' });
const state2 = router.getStateForAction({ type: 'Reset', actions: [{ type: 'Navigate', routeName: 'Foo', params: { bar: '42' } }, { type: 'Navigate', routeName: 'Bar' }], index: 1 }, state);
expect(state2 && state2.index).toEqual(1);
expect(state2 && state2.routes[0].params).toEqual({ bar: '42' });
expect(state2 && state2.routes[0].routeName).toEqual('Foo');
expect(state2 && state2.routes[1].routeName).toEqual('Bar');
});
});

View File

@@ -5,7 +5,9 @@
import React from 'react';
import TabRouter from '../TabRouter';
const INIT_ACTION = { type: 'Init' };
import NavigationActions from '../../NavigationActions';
const INIT_ACTION = { type: NavigationActions.INIT };
const BareLeafRouteConfig = {
screen: () => <div />,
@@ -19,13 +21,13 @@ describe('TabRouter', () => {
Foo: { screen: ScreenA },
Bar: { screen: ScreenB },
});
const state = router.getStateForAction({ type: 'Init' });
const state = router.getStateForAction({ type: NavigationActions.INIT });
const expectedState = {
index: 0,
routes: [{ key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }],
};
expect(state).toEqual(expectedState);
const state2 = router.getStateForAction({ type: 'Navigate', routeName: 'Bar' }, state);
const state2 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar' }, state);
const expectedState2 = {
index: 1,
routes: [{ key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }],
@@ -33,7 +35,7 @@ describe('TabRouter', () => {
expect(state2).toEqual(expectedState2);
expect(router.getComponentForState(expectedState)).toEqual(ScreenA);
expect(router.getComponentForState(expectedState2)).toEqual(ScreenB);
const state3 = router.getStateForAction({ type: 'Navigate', routeName: 'Bar' }, state2);
const state3 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar' }, state2);
expect(state3).toEqual(null);
});
@@ -44,13 +46,13 @@ describe('TabRouter', () => {
Foo: { getScreen: () => ScreenA },
Bar: { getScreen: () => ScreenB },
});
const state = router.getStateForAction({ type: 'Init' });
const state = router.getStateForAction({ type: NavigationActions.INIT });
const expectedState = {
index: 0,
routes: [{ key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }],
};
expect(state).toEqual(expectedState);
const state2 = router.getStateForAction({ type: 'Navigate', routeName: 'Bar' }, state);
const state2 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar' }, state);
const expectedState2 = {
index: 1,
routes: [{ key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }],
@@ -58,13 +60,13 @@ describe('TabRouter', () => {
expect(state2).toEqual(expectedState2);
expect(router.getComponentForState(expectedState)).toEqual(ScreenA);
expect(router.getComponentForState(expectedState2)).toEqual(ScreenB);
const state3 = router.getStateForAction({ type: 'Navigate', routeName: 'Bar' }, state2);
const state3 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar' }, state2);
expect(state3).toEqual(null);
});
test('Can set the initial tab', () => {
const router = TabRouter({ Foo: BareLeafRouteConfig, Bar: BareLeafRouteConfig }, { initialRouteName: 'Bar' });
const state = router.getStateForAction({ type: 'Init' });
const state = router.getStateForAction({ type: NavigationActions.INIT });
expect(state).toEqual({
index: 1,
routes: [{ key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }],
@@ -73,14 +75,14 @@ describe('TabRouter', () => {
test('getStateForAction returns null when navigating to same tab', () => {
const router = TabRouter({ Foo: BareLeafRouteConfig, Bar: BareLeafRouteConfig }, { initialRouteName: 'Bar' });
const state = router.getStateForAction({ type: 'Init' });
const state2 = router.getStateForAction({ type: 'Navigate', routeName: 'Bar' }, state);
const state = router.getStateForAction({ type: NavigationActions.INIT });
const state2 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar' }, state);
expect(state2).toEqual(null);
});
test('getStateForAction returns initial navigate', () => {
const router = TabRouter({ Foo: BareLeafRouteConfig, Bar: BareLeafRouteConfig });
const state = router.getStateForAction({ type: 'Navigate', routeName: 'Foo' });
const state = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Foo' });
expect(state && state.index).toEqual(0);
});
@@ -89,7 +91,7 @@ describe('TabRouter', () => {
ChildTabNavigator.router = TabRouter({ Foo: BareLeafRouteConfig, Bar: BareLeafRouteConfig });
const router = TabRouter({ Foo: BareLeafRouteConfig, Baz: { screen: ChildTabNavigator }, Boo: BareLeafRouteConfig });
const action = router.getActionForPathAndParams('Baz/Bar', { foo: '42' });
const navAction = { type: 'Navigate', routeName: 'Baz', action: { type: 'Navigate', routeName: 'Bar', params: { foo: '42' } } };
const navAction = { type: NavigationActions.NAVIGATE, routeName: 'Baz', action: { type: NavigationActions.NAVIGATE, routeName: 'Bar', params: { foo: '42' } } };
expect(action).toEqual(navAction);
const state = router.getStateForAction(navAction);
expect(state).toEqual({
@@ -126,7 +128,7 @@ describe('TabRouter', () => {
const ChildTabNavigator = () => <div />;
ChildTabNavigator.router = TabRouter({ Foo: BareLeafRouteConfig, Bar: BareLeafRouteConfig });
const router = TabRouter({ Foo: BareLeafRouteConfig, Baz: { screen: ChildTabNavigator }, Boo: BareLeafRouteConfig });
const state = router.getStateForAction({ type: 'Navigate', routeName: 'Bar' });
const state = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar' });
expect(state).toEqual({
index: 1,
routes: [
@@ -143,7 +145,7 @@ describe('TabRouter', () => {
{ key: 'Boo', routeName: 'Boo' },
],
});
const state2 = router.getStateForAction({ type: 'Navigate', routeName: 'Foo' }, state);
const state2 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Foo' }, state);
expect(state2).toEqual({
index: 1,
routes: [
@@ -160,7 +162,7 @@ describe('TabRouter', () => {
{ key: 'Boo', routeName: 'Boo' },
],
});
const state3 = router.getStateForAction({ type: 'Navigate', routeName: 'Foo' }, state2);
const state3 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Foo' }, state2);
expect(state3).toEqual(null);
});
@@ -198,7 +200,7 @@ describe('TabRouter', () => {
{ key: 'Gah', routeName: 'Gah' },
],
});
const state2 = router.getStateForAction({ type: 'Navigate', routeName: 'Zap' }, state);
const state2 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Zap' }, state);
expect(state2).toEqual({
index: 0,
routes: [
@@ -224,9 +226,9 @@ describe('TabRouter', () => {
{ key: 'Gah', routeName: 'Gah' },
],
});
const state3 = router.getStateForAction({ type: 'Navigate', routeName: 'Zap' }, state2);
const state3 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Zap' }, state2);
expect(state3).toEqual(null);
const state4 = router.getStateForAction({ type: 'Navigate', routeName: 'Foo', action: { type: 'Navigate', routeName: 'Bar', action: { type: 'Navigate', routeName: 'Zap' } } });
const state4 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Foo', action: { type: NavigationActions.NAVIGATE, routeName: 'Bar', action: { type: NavigationActions.NAVIGATE, routeName: 'Zap' } } });
expect(state4).toEqual({
index: 0,
routes: [
@@ -274,11 +276,11 @@ describe('TabRouter', () => {
foo: '42',
},
routeName: 'Bar',
type: 'Navigate',
type: NavigationActions.NAVIGATE,
};
expect(action).toEqual(expectedAction);
const state = router.getStateForAction({ type: 'Init' });
const state = router.getStateForAction({ type: NavigationActions.INIT });
const expectedState = {
index: 0,
routes: [{ key: 'Foo', routeName: 'Foo' }, { key: 'Bar', routeName: 'Bar' }],
@@ -315,7 +317,7 @@ describe('TabRouter', () => {
foo: '42',
},
routeName: 'Foo',
type: 'Navigate',
type: NavigationActions.NAVIGATE,
});
});
@@ -355,4 +357,11 @@ describe('TabRouter', () => {
const { path } = router.getPathAndParamsForState(state);
expect(path).toEqual('f/Baz');
});
test('Maps old actions (uses "getStateForAction returns null when navigating to same tab" test)', () => {
const router = TabRouter({ Foo: BareLeafRouteConfig, Bar: BareLeafRouteConfig }, { initialRouteName: 'Bar' });
const state = router.getStateForAction({ type: 'Init' });
const state2 = router.getStateForAction({ type: 'Navigate', routeName: 'Bar' }, state);
expect(state2).toEqual(null);
});
});

View File

@@ -14,6 +14,7 @@ import CardStackStyleInterpolator from './CardStackStyleInterpolator';
import CardStackPanResponder from './CardStackPanResponder';
import Header from './Header';
import NavigationPropTypes from '../PropTypes';
import NavigationActions from '../NavigationActions';
import addNavigationHelpers from '../addNavigationHelpers';
import SceneView from './SceneView';
@@ -120,8 +121,8 @@ class CardStack extends React.Component<DefaultProps, Props, void> {
/**
* The navigation prop, including the state and the dispatcher for the back
* action. The dispatcher must handle the back action ({type: 'Back'}), and
* the navigation state has this shape:
* action. The dispatcher must handle the back action
* ({ type: NavigationActions.BACK }), and the navigation state has this shape:
*
* ```js
* const navigationState = {
@@ -338,7 +339,7 @@ class CardStack extends React.Component<DefaultProps, Props, void> {
if (this.props.gesturesEnabled) {
let onNavigateBack = null;
if (this.props.navigation.state.index !== 0) {
onNavigateBack = () => this.props.navigation.dispatch({ type: 'Back', key: props.scene.route.key });
onNavigateBack = () => this.props.navigation.dispatch(NavigationActions.back({ key: props.scene.route.key }));
}
const panHandlersProps = {
...props,

View File

@@ -1,18 +1,17 @@
import React from 'react';
import { addNavigationHelpers } from 'react-navigation';
import { NavigationActions, addNavigationHelpers } from 'react-navigation';
function getAction(router, path, params) {
const action = router.getActionForPathAndParams(path, params);
if (action) {
return action;
}
return {
return NavigationActions.navigate({
params: { path },
routeName: 'NotFound',
type: 'Navigate',
};
});
}
module.exports = (NavigationAwareView) => {

View File

@@ -1,4 +1,5 @@
import React, { PropTypes, Component } from 'react';
import { NavigationActions } from 'react-navigation'
const isModifiedEvent = (event) =>
!!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
@@ -17,7 +18,7 @@ const Linkable = (Inner) => {
getAction = () => {
const {to, href} = this.props;
if (typeof to === 'string') {
return { type: 'Navigate', routeName: to };
return NavigationActions.navigate({ routeName: to });
} else if (typeof to === 'object' && typeof to.type === 'string') {
return to;
} else if (href) {

View File

@@ -2,7 +2,7 @@ import React, { Component } from 'react';
import Link from "./Link";
import { addNavigationHelpers } from 'react-navigation';
import { NavigationActions, addNavigationHelpers } from 'react-navigation';
const LinkableLi = Link.Linkable(props => <li {...props} />);
@@ -22,36 +22,31 @@ class PageWithSidebar extends Component {
let prevAction = null;
if (state.routes[state.index].index > 0) {
const prev = state.routes[state.index].index - 1;
prevAction = {
type: 'Navigate',
prevAction = NavigationActions.navigate({
routeName: state.routes[state.index].routes[prev].routeName,
};
});
}
if (!prevAction && state.index > 0) {
const prev = state.index - 1;
prevAction = {
type: 'Navigate',
prevAction = NavigationActions.navigate({
routeName: state.routes[prev].routeName,
action: {
type: 'Navigate',
action: NavigationActions.navigate({
routeName: state.routes[prev].routes[state.routes[prev].routes.length - 1].routeName,
}
};
})
});
}
let nextAction = null;
if (state.routes[state.index].index < state.routes[state.index].routes.length - 1) {
const next = state.routes[state.index].index + 1;
nextAction = {
type: 'Navigate',
nextAction = NavigationActions.navigate({
routeName: state.routes[state.index].routes[next].routeName,
};
});
}
if (!nextAction && state.index < state.routes.length - 1) {
const next = state.index + 1;
nextAction = {
type: 'Navigate',
nextAction = NavigationActions.navigate({
routeName: state.routes[next].routeName,
};
});
}
let prevName = prevAction && getConfig(router, state, prevAction, 'linkName');
let nextName = nextAction && getConfig(router, state, nextAction, 'linkName');

View File

@@ -10,7 +10,7 @@ const ReactDOMServer = require('react-dom/server');
import App from './App';
import { addNavigationHelpers } from 'react-navigation';
import { NavigationActions, addNavigationHelpers } from 'react-navigation';
class ServerApp extends React.Component {
static childContextTypes = {
@@ -41,7 +41,7 @@ function AppHandler(req, res) {
const path = req.url.substr(1)
let initAction = App.router.getActionForPathAndParams(path);
if (!initAction) {
initAction = { type: 'Navigate', routeName: 'NotFound', params: { path } };
initAction = NavigationActions.navigate({ routeName: 'NotFound', params: { path } });
status = 404;
}
const topNavigation = addNavigationHelpers({