Actions creators overhaul (#3619)

This commit is contained in:
Eric Vicenti
2018-03-25 21:31:59 -04:00
committed by Brent Vatne
parent 99ac5b6c08
commit 670d48366b
21 changed files with 316 additions and 241 deletions

View File

@@ -5347,7 +5347,7 @@ react-native-tab-view@^0.0.74:
dependencies:
prop-types "^15.6.0"
"react-native-tab-view@github:react-navigation/react-native-tab-view":
react-native-tab-view@react-navigation/react-native-tab-view:
version "0.0.74"
resolved "https://codeload.github.com/react-navigation/react-native-tab-view/tar.gz/36ebd834d78b841fc19778c966465d02fd1213bb"
dependencies:
@@ -5432,9 +5432,9 @@ react-navigation-header-buttons@^0.0.4:
dependencies:
react-native-platform-touchable "^1.1.1"
react-navigation-tabs@^0.1.0-alpha.1:
version "0.1.0-alpha.1"
resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-0.1.0-alpha.1.tgz#23188655fe70376afd9de51992294d72f4fcbd20"
react-navigation-tabs@0.1.0-alpha.3:
version "0.1.0-alpha.3"
resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-0.1.0-alpha.3.tgz#a68ace954e84206b7c3e6f5793f234d3931d03dc"
dependencies:
hoist-non-react-statics "^2.5.0"
prop-types "^15.6.0"

View File

@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { addNavigationHelpers, StackNavigator } from 'react-navigation';
import { StackNavigator } from 'react-navigation';
import LoginScreen from '../components/LoginScreen';
import MainScreen from '../components/MainScreen';
@@ -24,11 +24,11 @@ class AppWithNavigationState extends React.Component {
const { dispatch, nav } = this.props;
return (
<AppNavigator
navigation={addNavigationHelpers({
navigation={{
dispatch,
state: nav,
addListener,
})}
}}
/>
);
}

View File

@@ -1,30 +1,15 @@
const BACK = 'Navigation/BACK';
const INIT = 'Navigation/INIT';
const NAVIGATE = 'Navigation/NAVIGATE';
const POP = 'Navigation/POP';
const POP_TO_TOP = 'Navigation/POP_TO_TOP';
const PUSH = 'Navigation/PUSH';
const RESET = 'Navigation/RESET';
const REPLACE = 'Navigation/REPLACE';
const SET_PARAMS = 'Navigation/SET_PARAMS';
const URI = 'Navigation/URI';
const COMPLETE_TRANSITION = 'Navigation/COMPLETE_TRANSITION';
const OPEN_DRAWER = 'Navigation/OPEN_DRAWER';
const CLOSE_DRAWER = 'Navigation/CLOSE_DRAWER';
const TOGGLE_DRAWER = 'Navigation/TOGGLE_DRAWER';
const createAction = (type, fn) => {
fn.toString = () => type;
return fn;
};
const back = createAction(BACK, (payload = {}) => ({
const back = (payload = {}) => ({
type: BACK,
key: payload.key,
immediate: payload.immediate,
}));
});
const init = createAction(INIT, (payload = {}) => {
const init = (payload = {}) => {
const action = {
type: INIT,
};
@@ -32,9 +17,9 @@ const init = createAction(INIT, (payload = {}) => {
action.params = payload.params;
}
return action;
});
};
const navigate = createAction(NAVIGATE, payload => {
const navigate = payload => {
const action = {
type: NAVIGATE,
routeName: payload.routeName,
@@ -49,107 +34,24 @@ const navigate = createAction(NAVIGATE, payload => {
action.key = payload.key;
}
return action;
});
};
const pop = createAction(POP, payload => ({
type: POP,
n: payload && payload.n,
immediate: payload && payload.immediate,
}));
const popToTop = createAction(POP_TO_TOP, payload => ({
type: POP_TO_TOP,
immediate: payload && payload.immediate,
key: payload && payload.key,
}));
const push = createAction(PUSH, payload => {
const action = {
type: PUSH,
routeName: payload.routeName,
};
if (payload.params) {
action.params = payload.params;
}
if (payload.action) {
action.action = payload.action;
}
return action;
});
const reset = createAction(RESET, payload => ({
type: RESET,
index: payload.index,
key: payload.key,
actions: payload.actions,
}));
const replace = createAction(REPLACE, payload => ({
type: REPLACE,
key: payload.key,
newKey: payload.newKey,
params: payload.params,
action: payload.action,
routeName: payload.routeName,
immediate: payload.immediate,
}));
const setParams = createAction(SET_PARAMS, payload => ({
const setParams = payload => ({
type: SET_PARAMS,
key: payload.key,
params: payload.params,
}));
const uri = createAction(URI, payload => ({
type: URI,
uri: payload.uri,
}));
const completeTransition = createAction(COMPLETE_TRANSITION, payload => ({
type: COMPLETE_TRANSITION,
key: payload && payload.key,
}));
const openDrawer = createAction(OPEN_DRAWER, payload => ({
type: OPEN_DRAWER,
}));
const closeDrawer = createAction(CLOSE_DRAWER, payload => ({
type: CLOSE_DRAWER,
}));
const toggleDrawer = createAction(TOGGLE_DRAWER, payload => ({
type: TOGGLE_DRAWER,
}));
});
export default {
// Action constants
BACK,
INIT,
NAVIGATE,
POP,
POP_TO_TOP,
PUSH,
RESET,
REPLACE,
SET_PARAMS,
URI,
COMPLETE_TRANSITION,
OPEN_DRAWER,
CLOSE_DRAWER,
TOGGLE_DRAWER,
// Action creators
back,
init,
navigate,
pop,
popToTop,
push,
reset,
replace,
setParams,
uri,
completeTransition,
openDrawer,
closeDrawer,
toggleDrawer,
};

View File

@@ -1,11 +1,10 @@
import NavigationActions from '../NavigationActions';
describe('actions', () => {
describe('generic navigation actions', () => {
const params = { foo: 'bar' };
const navigateAction = NavigationActions.navigate({ routeName: 'another' });
it('exports back action and type', () => {
expect(NavigationActions.back.toString()).toEqual(NavigationActions.BACK);
expect(NavigationActions.back()).toEqual({ type: NavigationActions.BACK });
expect(NavigationActions.back({ key: 'test' })).toEqual({
type: NavigationActions.BACK,
@@ -14,7 +13,6 @@ describe('actions', () => {
});
it('exports init action and type', () => {
expect(NavigationActions.init.toString()).toEqual(NavigationActions.INIT);
expect(NavigationActions.init()).toEqual({ type: NavigationActions.INIT });
expect(NavigationActions.init({ params })).toEqual({
type: NavigationActions.INIT,
@@ -23,9 +21,6 @@ describe('actions', () => {
});
it('exports navigate action and type', () => {
expect(NavigationActions.navigate.toString()).toEqual(
NavigationActions.NAVIGATE
);
expect(NavigationActions.navigate({ routeName: 'test' })).toEqual({
type: NavigationActions.NAVIGATE,
routeName: 'test',
@@ -47,36 +42,7 @@ describe('actions', () => {
});
});
it('exports reset action and type', () => {
expect(NavigationActions.reset.toString()).toEqual(NavigationActions.RESET);
expect(NavigationActions.reset({ index: 0, actions: [] })).toEqual({
type: NavigationActions.RESET,
index: 0,
actions: [],
});
expect(
NavigationActions.reset({
index: 0,
key: 'test',
actions: [navigateAction],
})
).toEqual({
type: NavigationActions.RESET,
index: 0,
key: 'test',
actions: [
{
type: NavigationActions.NAVIGATE,
routeName: 'another',
},
],
});
});
it('exports setParams action and type', () => {
expect(NavigationActions.setParams.toString()).toEqual(
NavigationActions.SET_PARAMS
);
expect(
NavigationActions.setParams({
key: 'test',
@@ -88,12 +54,4 @@ describe('actions', () => {
params,
});
});
it('exports uri action and type', () => {
expect(NavigationActions.uri.toString()).toEqual(NavigationActions.URI);
expect(NavigationActions.uri({ uri: 'http://google.com' })).toEqual({
type: NavigationActions.URI,
uri: 'http://google.com',
});
});
});

View File

@@ -4,7 +4,6 @@ import withLifecyclePolyfill from 'react-lifecycles-compat';
import { BackHandler } from './PlatformHelpers';
import NavigationActions from './NavigationActions';
import addNavigationHelpers from './addNavigationHelpers';
import invariant from './utils/invariant';
import docsUrl from './utils/docsUrl';
@@ -327,7 +326,7 @@ export default function createNavigationContainer(Component) {
return this._renderLoading();
}
if (!this._navigation || this._navigation.state !== nav) {
this._navigation = addNavigationHelpers({
this._navigation = {
dispatch: this.dispatch,
state: nav,
addListener: (eventName, handler) => {
@@ -341,7 +340,7 @@ export default function createNavigationContainer(Component) {
},
};
},
});
};
}
navigation = this._navigation;
}

View File

@@ -1,7 +1,6 @@
import React from 'react';
import getChildEventSubscriber from '../getChildEventSubscriber';
import addNavigationHelpers from '../addNavigationHelpers';
function createNavigator(NavigatorView, router, navigationConfig) {
class Navigator extends React.Component {
@@ -53,13 +52,35 @@ function createNavigator(NavigatorView, router, navigationConfig) {
);
}
const childNavigation = addNavigationHelpers({
const actionCreators = {
...navigation.actions,
...router.getActionCreators(route, state.key),
};
const actionHelpers = {};
Object.keys(actionCreators).forEach(actionName => {
actionHelpers[actionName] = (...args) => {
const actionCreator = actionCreators[actionName];
const action = actionCreator(...args);
dispatch(action);
};
});
const childNavigation = {
...actionHelpers,
actions: actionCreators,
dispatch,
state: route,
dangerouslyGetParent: this._dangerouslyGetParent,
addListener: this.childEventSubscribers[route.key].addListener,
isFocused: () => this._isRouteFocused(route),
});
getParam: (paramName, defaultValue) => {
const params = route.params;
if (params && paramName in params) {
return params[paramName];
}
return defaultValue;
},
};
const options = router.getScreenOptions(childNavigation, screenProps);
descriptors[route.key] = {

View File

@@ -8,12 +8,6 @@ module.exports = {
get StateUtils() {
return require('./StateUtils').default;
},
get addNavigationHelpers() {
return require('./addNavigationHelpers').default;
},
get NavigationActions() {
return require('./NavigationActions').default;
},
// Navigators
get createNavigator() {
@@ -69,6 +63,17 @@ module.exports = {
return require('react-navigation-tabs').createMaterialTopTabNavigator;
},
// Actions
get NavigationActions() {
return require('./NavigationActions').default;
},
get StackActions() {
return require('./routers/StackActions').default;
},
get DrawerActions() {
return require('./routers/DrawerActions').default;
},
// Routers
get StackRouter() {
return require('./routers/StackRouter').default;

View File

@@ -8,18 +8,23 @@ module.exports = {
get StateUtils() {
return require('./StateUtils').default;
},
get addNavigationHelpers() {
return require('./addNavigationHelpers').default;
},
get NavigationActions() {
return require('./NavigationActions').default;
},
// Navigators
get createNavigator() {
return require('./navigators/createNavigator').default;
},
// Actions
get NavigationActions() {
return require('./NavigationActions').default;
},
get StackActions() {
return require('./routers/StackActions').default;
},
get DrawerActions() {
return require('./routers/DrawerActions').default;
},
// Routers
get StackRouter() {
return require('./routers/StackRouter').default;
@@ -27,6 +32,9 @@ module.exports = {
get TabRouter() {
return require('./routers/TabRouter').default;
},
get SwitchRouter() {
return require('./routers/SwitchRouter').default;
},
// HOCs
get withNavigation() {

View File

@@ -0,0 +1,28 @@
const OPEN_DRAWER = 'Navigation/OPEN_DRAWER';
const CLOSE_DRAWER = 'Navigation/CLOSE_DRAWER';
const TOGGLE_DRAWER = 'Navigation/TOGGLE_DRAWER';
const openDrawer = payload => ({
type: OPEN_DRAWER,
...payload,
});
const closeDrawer = payload => ({
type: CLOSE_DRAWER,
...payload,
});
const toggleDrawer = payload => ({
type: TOGGLE_DRAWER,
...payload,
});
export default {
OPEN_DRAWER,
CLOSE_DRAWER,
TOGGLE_DRAWER,
openDrawer,
closeDrawer,
toggleDrawer,
};

View File

@@ -4,6 +4,8 @@ import NavigationActions from '../NavigationActions';
import invariant from '../utils/invariant';
import withDefaultValue from '../utils/withDefaultValue';
import DrawerActions from './DrawerActions';
export default (routeConfigs, config = {}) => {
config = { ...config };
config = withDefaultValue(config, 'resetOnBlur', false);
@@ -14,6 +16,15 @@ export default (routeConfigs, config = {}) => {
return {
...switchRouter,
getActionCreators(route, navStateKey) {
return {
openDrawer: () => ({ type: DrawerActions.OPEN_DRAWER }),
closeDrawer: () => ({ type: DrawerActions.CLOSE_DRAWER }),
toggleDrawer: () => ({ type: DrawerActions.TOGGLE_DRAWER }),
...switchRouter.getActionCreators(route, navStateKey),
};
},
getStateForAction(action, lastState) {
const state = lastState || {
...switchRouter.getStateForAction(action, undefined),
@@ -21,25 +32,19 @@ export default (routeConfigs, config = {}) => {
};
// Handle explicit drawer actions
if (
state.isDrawerOpen &&
action.type === NavigationActions.CLOSE_DRAWER
) {
if (state.isDrawerOpen && action.type === DrawerActions.CLOSE_DRAWER) {
return {
...state,
isDrawerOpen: false,
};
}
if (
!state.isDrawerOpen &&
action.type === NavigationActions.OPEN_DRAWER
) {
if (!state.isDrawerOpen && action.type === DrawerActions.OPEN_DRAWER) {
return {
...state,
isDrawerOpen: true,
};
}
if (action.type === NavigationActions.TOGGLE_DRAWER) {
if (action.type === DrawerActions.TOGGLE_DRAWER) {
return {
...state,
isDrawerOpen: !state.isDrawerOpen,

View File

@@ -0,0 +1,52 @@
const POP = 'Navigation/POP';
const POP_TO_TOP = 'Navigation/POP_TO_TOP';
const PUSH = 'Navigation/PUSH';
const RESET = 'Navigation/RESET';
const REPLACE = 'Navigation/REPLACE';
const COMPLETE_TRANSITION = 'Navigation/COMPLETE_TRANSITION';
const pop = payload => ({
type: POP,
...payload,
});
const popToTop = payload => ({
type: POP_TO_TOP,
...payload,
});
const push = payload => ({
type: PUSH,
...payload,
});
const reset = payload => ({
type: RESET,
...payload,
});
const replace = payload => ({
type: REPLACE,
...payload,
});
const completeTransition = payload => ({
type: COMPLETE_TRANSITION,
...payload,
});
export default {
POP,
POP_TO_TOP,
PUSH,
RESET,
REPLACE,
COMPLETE_TRANSITION,
pop,
popToTop,
push,
reset,
replace,
completeTransition,
};

View File

@@ -1,12 +1,14 @@
import pathToRegexp from 'path-to-regexp';
import NavigationActions from '../NavigationActions';
import StackActions from './StackActions';
import createConfigGetter from './createConfigGetter';
import getScreenForRouteName from './getScreenForRouteName';
import StateUtils from '../StateUtils';
import validateRouteConfigMap from './validateRouteConfigMap';
import invariant from '../utils/invariant';
import { generateKey } from './KeyGenerator';
import getNavigationActionCreators from './getNavigationActionCreators';
function isEmpty(obj) {
if (!obj) return true;
@@ -19,7 +21,7 @@ function isEmpty(obj) {
function behavesLikePushAction(action) {
return (
action.type === NavigationActions.NAVIGATE ||
action.type === NavigationActions.PUSH
action.type === StackActions.PUSH
);
}
@@ -42,7 +44,7 @@ export default (routeConfigs, stackConfig = {}) => {
}
});
const { initialRouteParams } = stackConfig;
const { initialRouteParams, getActionCreators } = stackConfig;
const initialRouteName = stackConfig.initialRouteName || routeNames[0];
@@ -136,7 +138,7 @@ export default (routeConfigs, stackConfig = {}) => {
});
paths = Object.entries(pathsByRouteNames);
paths.sort((a: [string, *], b: [string, *]) => b[1].priority - a[1].priority);
paths.sort((a, b) => b[1].priority - a[1].priority);
return {
getComponentForState(state) {
@@ -152,6 +154,45 @@ export default (routeConfigs, stackConfig = {}) => {
return getScreenForRouteName(routeConfigs, routeName);
},
getActionCreators(route, navStateKey) {
return {
...getNavigationActionCreators(route, navStateKey),
...(getActionCreators ? getActionCreators(route, navStateKey) : {}),
pop: (n, params) => ({
type: StackActions.POP,
n,
...params,
}),
popToTop: params => ({
type: StackActions.POP_TO_TOP,
...params,
}),
push: (routeName, params, action) => ({
type: StackActions.PUSH,
routeName,
params,
action,
}),
replace: (routeName, params, action) => ({
type: StackActions.REPLACE,
routeName,
params,
action,
key: route.key,
}),
reset: (actions, index) => ({
type: StackActions.RESET,
actions,
index: index == null ? actions.length - 1 : index,
key: navStateKey,
}),
dismiss: () => ({
type: NavigationActions.BACK,
key: navStateKey,
}),
};
},
getStateForAction(action, state) {
// Set up the initial state if needed
if (!state) {
@@ -160,7 +201,7 @@ export default (routeConfigs, stackConfig = {}) => {
// Check if the focused child scene wants to handle the action, as long as
// it is not a reset to the root stack
if (action.type !== NavigationActions.RESET || action.key !== null) {
if (action.type !== StackActions.RESET || action.key !== null) {
const keyIndex = action.key
? StateUtils.indexOf(state, action.key)
: -1;
@@ -192,7 +233,7 @@ export default (routeConfigs, stackConfig = {}) => {
let route;
invariant(
action.type !== NavigationActions.PUSH || action.key == null,
action.type !== StackActions.PUSH || action.key == null,
'StackRouter does not support key on the push action'
);
@@ -206,7 +247,7 @@ export default (routeConfigs, stackConfig = {}) => {
}
});
if (action.type !== NavigationActions.PUSH && lastRouteIndex !== -1) {
if (action.type !== StackActions.PUSH && lastRouteIndex !== -1) {
// If index is unchanged and params are not being set, leave state identity intact
if (state.index === lastRouteIndex && !action.params) {
return null;
@@ -260,7 +301,7 @@ export default (routeConfigs, stackConfig = {}) => {
isTransitioning: action.immediate !== true,
};
} else if (
action.type === NavigationActions.PUSH &&
action.type === StackActions.PUSH &&
childRouters[action.routeName] === undefined
) {
// Return the state identity to bubble the action up
@@ -304,7 +345,7 @@ export default (routeConfigs, stackConfig = {}) => {
}
// Handle pop-to-top behavior. Make sure this happens after children have had a chance to handle the action, so that the inner stack pops to top first.
if (action.type === NavigationActions.POP_TO_TOP) {
if (action.type === StackActions.POP_TO_TOP) {
// Refuse to handle pop to top if a key is given that doesn't correspond
// to this router
if (action.key && state.key !== action.key) {
@@ -325,7 +366,7 @@ export default (routeConfigs, stackConfig = {}) => {
}
// Handle replace action
if (action.type === NavigationActions.REPLACE) {
if (action.type === StackActions.REPLACE) {
const routeIndex = state.routes.findIndex(r => r.key === action.key);
// Only replace if the key matches one of our routes
if (routeIndex !== -1) {
@@ -351,7 +392,7 @@ export default (routeConfigs, stackConfig = {}) => {
// Update transitioning state
if (
action.type === NavigationActions.COMPLETE_TRANSITION &&
action.type === StackActions.COMPLETE_TRANSITION &&
(action.key == null || action.key === state.key) &&
state.isTransitioning
) {
@@ -381,7 +422,7 @@ export default (routeConfigs, stackConfig = {}) => {
}
}
if (action.type === NavigationActions.RESET) {
if (action.type === StackActions.RESET) {
// Only handle reset actions that are unspecified or match this state key
if (action.key != null && action.key != state.key) {
// Deliberately use != instead of !== so we can match null with
@@ -418,11 +459,11 @@ export default (routeConfigs, stackConfig = {}) => {
if (
action.type === NavigationActions.BACK ||
action.type === NavigationActions.POP
action.type === StackActions.POP
) {
const { key, n, immediate } = action;
let backRouteIndex = state.index;
if (action.type === NavigationActions.POP && n != null) {
if (action.type === StackActions.POP && n != null) {
// determine the index to go back *from*. In this case, n=1 means to go
// back from state.index, as if it were a normal "BACK" action
backRouteIndex = Math.max(1, state.index - n + 1);

View File

@@ -3,12 +3,15 @@ import getScreenForRouteName from './getScreenForRouteName';
import createConfigGetter from './createConfigGetter';
import NavigationActions from '../NavigationActions';
import StackActions from './StackActions';
import validateRouteConfigMap from './validateRouteConfigMap';
import getNavigationActionCreators from './getNavigationActionCreators';
function childrenUpdateWithoutSwitchingIndex(actionType) {
return [
NavigationActions.SET_PARAMS,
NavigationActions.COMPLETE_TRANSITION,
// Todo: make SwitchRouter not depend on StackActions..
StackActions.COMPLETE_TRANSITION,
].includes(actionType);
}
@@ -98,6 +101,10 @@ export default (routeConfigs, config = {}) => {
return nextState;
},
getActionCreators(route, stateKey) {
return getNavigationActionCreators(route, stateKey);
},
getStateForAction(action, inputState) {
let prevState = inputState ? { ...inputState } : inputState;
let state = inputState || this.getInitialState();

View File

@@ -4,6 +4,7 @@ import React from 'react';
import DrawerRouter from '../DrawerRouter';
import NavigationActions from '../../NavigationActions';
import DrawerActions from '../../routers/DrawerActions';
const INIT_ACTION = { type: NavigationActions.INIT };
@@ -54,17 +55,17 @@ describe('DrawerRouter', () => {
const state = router.getStateForAction(INIT_ACTION);
expect(state.isDrawerOpen).toEqual(false);
const state2 = router.getStateForAction(
{ type: NavigationActions.OPEN_DRAWER },
{ type: DrawerActions.OPEN_DRAWER },
state
);
expect(state2.isDrawerOpen).toEqual(true);
const state3 = router.getStateForAction(
{ type: NavigationActions.CLOSE_DRAWER },
{ type: DrawerActions.CLOSE_DRAWER },
state2
);
expect(state3.isDrawerOpen).toEqual(false);
const state4 = router.getStateForAction(
{ type: NavigationActions.TOGGLE_DRAWER },
{ type: DrawerActions.TOGGLE_DRAWER },
state3
);
expect(state4.isDrawerOpen).toEqual(true);

View File

@@ -6,7 +6,6 @@ import StackRouter from '../StackRouter';
import TabRouter from '../TabRouter';
import NavigationActions from '../../NavigationActions';
import addNavigationHelpers from '../../addNavigationHelpers';
import { _TESTING_ONLY_normalize_keys } from '../KeyGenerator';
beforeEach(() => {
@@ -58,31 +57,31 @@ Object.keys(ROUTERS).forEach(routerName => {
];
expect(
router.getScreenOptions(
addNavigationHelpers({
{
state: routes[0],
dispatch: () => false,
addListener: dummyEventSubscriber,
}),
},
{}
).title
).toEqual(undefined);
expect(
router.getScreenOptions(
addNavigationHelpers({
{
state: routes[1],
dispatch: () => false,
addListener: dummyEventSubscriber,
}),
},
{}
).title
).toEqual('BarTitle');
expect(
router.getScreenOptions(
addNavigationHelpers({
{
state: routes[2],
dispatch: () => false,
addListener: dummyEventSubscriber,
}),
},
{}
).title
).toEqual('Baz-123');

View File

@@ -3,11 +3,11 @@
import React from 'react';
import StackRouter from '../StackRouter';
import StackActions from '../StackActions';
import NavigationActions from '../../NavigationActions';
import TabRouter from '../TabRouter';
import { _TESTING_ONLY_normalize_keys } from '../KeyGenerator';
import NavigationActions from '../../NavigationActions';
beforeEach(() => {
_TESTING_ONLY_normalize_keys();
});
@@ -388,7 +388,7 @@ describe('StackRouter', () => {
const barKey = state2.routes[1].routes[0].key;
const state3 = router.getStateForAction(
{
type: NavigationActions.PUSH,
type: StackActions.PUSH,
routeName: 'Bad',
},
state2
@@ -420,7 +420,7 @@ describe('StackRouter', () => {
const barKey = state2.routes[1].routes[0].key;
const state3 = router.getStateForAction(
{
type: NavigationActions.POP,
type: StackActions.POP,
},
state2
);
@@ -448,7 +448,7 @@ describe('StackRouter', () => {
const barKey = state2.routes[1].routes[0].key;
const state3 = router.getStateForAction(
{
type: NavigationActions.POP_TO_TOP,
type: StackActions.POP_TO_TOP,
},
state2
);
@@ -476,7 +476,7 @@ describe('StackRouter', () => {
const barKey = state2.routes[1].routes[0].key;
const state3 = router.getStateForAction(
{
type: NavigationActions.POP_TO_TOP,
type: StackActions.POP_TO_TOP,
key: state2.key,
},
state2
@@ -500,19 +500,19 @@ describe('StackRouter', () => {
],
};
const poppedState = TestRouter.getStateForAction(
NavigationActions.popToTop(),
StackActions.popToTop(),
state
);
expect(poppedState.routes.length).toBe(1);
expect(poppedState.index).toBe(0);
expect(poppedState.isTransitioning).toBe(true);
const poppedState2 = TestRouter.getStateForAction(
NavigationActions.popToTop(),
StackActions.popToTop(),
poppedState
);
expect(poppedState).toEqual(poppedState2);
const poppedImmediatelyState = TestRouter.getStateForAction(
NavigationActions.popToTop({ immediate: true }),
StackActions.popToTop({ immediate: true }),
state
);
expect(poppedImmediatelyState.routes.length).toBe(1);
@@ -681,14 +681,14 @@ describe('StackRouter', () => {
});
const initState = TestRouter.getStateForAction(NavigationActions.init());
const pushedState = TestRouter.getStateForAction(
NavigationActions.push({ routeName: 'bar' }),
StackActions.push({ routeName: 'bar' }),
initState
);
expect(pushedState.index).toEqual(1);
expect(pushedState.routes[1].routeName).toEqual('bar');
expect(() => {
TestRouter.getStateForAction(
{ type: NavigationActions.PUSH, routeName: 'bar', key: 'a' },
{ type: StackActions.PUSH, routeName: 'bar', key: 'a' },
pushedState
);
}).toThrow();
@@ -701,13 +701,13 @@ describe('StackRouter', () => {
});
const initState = TestRouter.getStateForAction(NavigationActions.init());
const pushedState = TestRouter.getStateForAction(
NavigationActions.push({ routeName: 'bar' }),
StackActions.push({ routeName: 'bar' }),
initState
);
expect(pushedState.index).toEqual(1);
expect(pushedState.routes[1].routeName).toEqual('bar');
const secondPushedState = TestRouter.getStateForAction(
NavigationActions.push({ routeName: 'bar' }),
StackActions.push({ routeName: 'bar' }),
pushedState
);
expect(secondPushedState.index).toEqual(2);
@@ -807,7 +807,7 @@ describe('StackRouter', () => {
NavigationActions.navigate({ routeName: 'foo' })
);
const replacedState = TestRouter.getStateForAction(
NavigationActions.replace({
StackActions.replace({
routeName: 'bar',
params: { meaning: 42 },
key: initState.routes[0].key,
@@ -820,7 +820,7 @@ describe('StackRouter', () => {
expect(replacedState.routes[0].routeName).toEqual('bar');
expect(replacedState.routes[0].params.meaning).toEqual(42);
const replacedState2 = TestRouter.getStateForAction(
NavigationActions.replace({
StackActions.replace({
routeName: 'bar',
key: initState.routes[0].key,
newKey: 'wow',
@@ -857,7 +857,7 @@ describe('StackRouter', () => {
expect(state2 && state2.isTransitioning).toEqual(true);
const state3 = router.getStateForAction(
{
type: NavigationActions.COMPLETE_TRANSITION,
type: StackActions.COMPLETE_TRANSITION,
},
state2
);
@@ -1125,7 +1125,7 @@ describe('StackRouter', () => {
const state = router.getStateForAction({ type: NavigationActions.INIT });
const state2 = router.getStateForAction(
{
type: NavigationActions.RESET,
type: StackActions.RESET,
actions: [
{
type: NavigationActions.NAVIGATE,
@@ -1160,7 +1160,7 @@ describe('StackRouter', () => {
});
const state1 = router.getStateForAction({ type: NavigationActions.INIT });
const resetAction = {
type: NavigationActions.RESET,
type: StackActions.RESET,
key: 'Bad Key',
actions: [
{
@@ -1213,7 +1213,7 @@ describe('StackRouter', () => {
const state = router.getStateForAction({ type: NavigationActions.INIT });
const state2 = router.getStateForAction(
{
type: NavigationActions.RESET,
type: StackActions.RESET,
actions: [
{
type: NavigationActions.NAVIGATE,
@@ -1265,7 +1265,7 @@ describe('StackRouter', () => {
);
const state3 = router.getStateForAction(
{
type: NavigationActions.RESET,
type: StackActions.RESET,
key: 'Init',
actions: [
{
@@ -1280,7 +1280,7 @@ describe('StackRouter', () => {
);
const state4 = router.getStateForAction(
{
type: NavigationActions.RESET,
type: StackActions.RESET,
key: null,
actions: [
{
@@ -1752,7 +1752,7 @@ test('Handles deep navigate completion action', () => {
expect(!!key).toEqual(true);
const state3 = router.getStateForAction(
{
type: NavigationActions.COMPLETE_TRANSITION,
type: StackActions.COMPLETE_TRANSITION,
},
state2
);

View File

@@ -4,6 +4,7 @@ import React from 'react';
import TabRouter from '../TabRouter';
import StackRouter from '../StackRouter';
import StackActions from '../../routers/StackActions';
import NavigationActions from '../../NavigationActions';
const INIT_ACTION = { type: NavigationActions.INIT };
@@ -710,16 +711,13 @@ describe('TabRouter', () => {
{ key: 'D', routeName: 'bar' },
],
};
const poppedState = TestRouter.getStateForAction(
NavigationActions.pop(),
state
);
const poppedState = TestRouter.getStateForAction(StackActions.pop(), state);
expect(poppedState.routes.length).toBe(3);
expect(poppedState.index).toBe(2);
expect(poppedState.isTransitioning).toBe(true);
const poppedState2 = TestRouter.getStateForAction(
NavigationActions.pop({ n: 2, immediate: true }),
StackActions.pop({ n: 2, immediate: true }),
state
);
expect(poppedState2.routes.length).toBe(2);
@@ -727,7 +725,7 @@ describe('TabRouter', () => {
expect(poppedState2.isTransitioning).toBe(false);
const poppedState3 = TestRouter.getStateForAction(
NavigationActions.pop({ n: 5 }),
StackActions.pop({ n: 5 }),
state
);
expect(poppedState3.routes.length).toBe(1);

View File

@@ -0,0 +1,49 @@
import NavigationActions from '../NavigationActions';
const getNavigationActionCreators = route => {
return {
goBack: key => {
let actualizedKey = key;
if (key === undefined && navigation.state.key) {
invariant(
typeof navigation.state.key === 'string',
'key should be a string'
);
actualizedKey = navigation.state.key;
}
return NavigationActions.back({ key: actualizedKey });
},
navigate: (navigateTo, params, action) => {
if (typeof navigateTo === 'string') {
return NavigationActions.navigate({
routeName: navigateTo,
params,
action,
});
}
invariant(
typeof navigateTo === 'object',
'Must navigateTo an object or a string'
);
invariant(
params == null,
'Params must not be provided to .navigate() when specifying an object'
);
invariant(
action == null,
'Child action must not be provided to .navigate() when specifying an object'
);
return NavigationActions.navigate(navigateTo);
},
setParams: params => {
invariant(
navigation.state.key && typeof navigation.state.key === 'string',
'setParams cannot be called by root navigator'
);
const key = navigation.state.key;
return NavigationActions.setParams({ params, key });
},
};
};
export default getNavigationActionCreators;

View File

@@ -2,9 +2,9 @@ import React from 'react';
import { Dimensions } from 'react-native';
import DrawerLayout from 'react-native-drawer-layout-polyfill';
import addNavigationHelpers from '../../addNavigationHelpers';
import DrawerSidebar from './DrawerSidebar';
import NavigationActions from '../../NavigationActions';
import DrawerActions from '../../routers/DrawerActions';
/**
* Component that renders the drawer.
@@ -40,7 +40,7 @@ export default class DrawerView extends React.PureComponent {
const { navigation } = this.props;
const { isDrawerOpen } = navigation.state;
if (!isDrawerOpen) {
navigation.dispatch({ type: NavigationActions.OPEN_DRAWER });
navigation.dispatch({ type: DrawerActions.OPEN_DRAWER });
}
};
@@ -48,7 +48,7 @@ export default class DrawerView extends React.PureComponent {
const { navigation } = this.props;
const { isDrawerOpen } = navigation.state;
if (isDrawerOpen) {
navigation.dispatch({ type: NavigationActions.CLOSE_DRAWER });
navigation.dispatch({ type: DrawerActions.CLOSE_DRAWER });
}
};

View File

@@ -4,6 +4,7 @@ import { NativeModules } from 'react-native';
import StackViewLayout from './StackViewLayout';
import Transitioner from '../Transitioner';
import NavigationActions from '../../NavigationActions';
import StackActions from '../../routers/StackActions';
import TransitionConfigs from './StackViewTransitionConfigs';
const NativeAnimatedModule =
@@ -27,7 +28,7 @@ class StackView extends React.Component {
onTransitionEnd={(lastTransition, transition) => {
const { onTransitionEnd, navigation } = this.props;
navigation.dispatch(
NavigationActions.completeTransition({
StackActions.completeTransition({
key: navigation.state.key,
})
);

View File

@@ -14,6 +14,7 @@ import {
import Card from './StackViewCard';
import Header from '../Header/Header';
import NavigationActions from '../../NavigationActions';
import StackActions from '../../routers/StackActions';
import SceneView from '../SceneView';
import { NavigationProvider } from '../NavigationContext';
@@ -178,7 +179,7 @@ class StackViewLayout extends React.Component {
immediate: true,
})
);
navigation.dispatch(NavigationActions.completeTransition());
navigation.dispatch(StackActions.completeTransition());
}
};