mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-04-27 21:08:02 +08:00
refactor: add a type property to router and state (#146)
The `type` property denotes the type of the router. It can be used to verify compatibility of navigation state and the router when rehydrating state, making rehydration more resilient. It can also help our utilities to detect the type of the navigator to properly implement some functionality. For example, the `useScrollToTop` hook can now know if it's not inside a tab navigator and needs to find the tab navigator in a parent.
This commit is contained in:
committed by
Michał Osadnik
parent
fb749ac064
commit
3d9db6ff25
@@ -4,7 +4,8 @@ import * as CommonActions from '../CommonActions';
|
||||
jest.mock('shortid', () => () => 'test');
|
||||
|
||||
const STATE = {
|
||||
stale: false as false,
|
||||
stale: false as const,
|
||||
type: 'test',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routes: [
|
||||
@@ -23,6 +24,7 @@ it('replaces focused screen with REPLACE', () => {
|
||||
|
||||
expect(result).toEqual({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routes: [
|
||||
@@ -42,6 +44,7 @@ it('replaces source screen with REPLACE', () => {
|
||||
|
||||
expect(result).toEqual({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routes: [
|
||||
@@ -70,6 +73,7 @@ it('sets params for the focused screen with SET_PARAMS', () => {
|
||||
|
||||
expect(result).toEqual({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routes: [
|
||||
@@ -89,6 +93,7 @@ it('sets params for the source screen with SET_PARAMS', () => {
|
||||
|
||||
expect(result).toEqual({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routes: [
|
||||
|
||||
@@ -233,6 +233,7 @@ it('handle dispatching with ref', () => {
|
||||
expect(onStateChange).toBeCalledTimes(1);
|
||||
expect(onStateChange).lastCalledWith({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 0,
|
||||
key: '0',
|
||||
routeNames: ['foo', 'foo2', 'bar', 'baz'],
|
||||
@@ -242,6 +243,7 @@ it('handle dispatching with ref', () => {
|
||||
name: 'baz',
|
||||
state: {
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 0,
|
||||
key: '1',
|
||||
routeNames: ['qux', 'lex'],
|
||||
@@ -367,10 +369,12 @@ it('handle getRootState', () => {
|
||||
routeNames: ['qux', 'lex'],
|
||||
routes: [{ key: 'qux', name: 'qux' }, { key: 'lex', name: 'lex' }],
|
||||
stale: false,
|
||||
type: 'test',
|
||||
},
|
||||
},
|
||||
{ key: 'bar', name: 'bar' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'test',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,6 +13,8 @@ export const MockRouterKey = { current: 0 };
|
||||
|
||||
export default function MockRouter(options: DefaultRouterOptions) {
|
||||
const router: Router<NavigationState, MockActions> = {
|
||||
type: 'test',
|
||||
|
||||
getInitialState({ routeNames, routeParamList }) {
|
||||
const index =
|
||||
options.initialRouteName === undefined
|
||||
@@ -21,6 +23,7 @@ export default function MockRouter(options: DefaultRouterOptions) {
|
||||
|
||||
return {
|
||||
stale: false,
|
||||
type: 'test',
|
||||
key: String(MockRouterKey.current++),
|
||||
index,
|
||||
routeNames,
|
||||
@@ -58,6 +61,7 @@ export default function MockRouter(options: DefaultRouterOptions) {
|
||||
|
||||
return {
|
||||
stale: false,
|
||||
type: 'test',
|
||||
key: String(MockRouterKey.current++),
|
||||
index:
|
||||
typeof state.index === 'number' && state.index < routes.length
|
||||
|
||||
@@ -52,6 +52,7 @@ it('initializes state for a navigator on navigation', () => {
|
||||
expect(onStateChange).toBeCalledTimes(1);
|
||||
expect(onStateChange).toBeCalledWith({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 0,
|
||||
key: '0',
|
||||
routeNames: ['foo', 'bar', 'baz'],
|
||||
@@ -106,6 +107,66 @@ it('rehydrates state for a navigator on navigation', () => {
|
||||
routeNames: ['foo', 'bar'],
|
||||
routes: [{ key: 'foo', name: 'foo' }, { key: 'bar', name: 'bar' }],
|
||||
stale: false,
|
||||
type: 'test',
|
||||
});
|
||||
});
|
||||
|
||||
it("doesn't rehydrate state if the type of state didn't match router", () => {
|
||||
const TestNavigator = (props: any) => {
|
||||
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
|
||||
|
||||
return descriptors[state.routes[state.index].key].render();
|
||||
};
|
||||
|
||||
const FooScreen = (props: any) => {
|
||||
React.useEffect(() => {
|
||||
props.navigation.dispatch({ type: 'UPDATE' });
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
index: 1,
|
||||
type: 'something-else',
|
||||
routes: [{ key: 'foo', name: 'foo' }, { key: 'bar', name: 'bar' }],
|
||||
};
|
||||
|
||||
const onStateChange = jest.fn();
|
||||
|
||||
const element = (
|
||||
<NavigationContainer
|
||||
initialState={initialState}
|
||||
onStateChange={onStateChange}
|
||||
>
|
||||
<TestNavigator initialRouteName="foo">
|
||||
<Screen
|
||||
name="foo"
|
||||
component={FooScreen}
|
||||
initialParams={{ answer: 42 }}
|
||||
/>
|
||||
<Screen name="bar" component={jest.fn()} />
|
||||
</TestNavigator>
|
||||
</NavigationContainer>
|
||||
);
|
||||
|
||||
render(element).update(element);
|
||||
|
||||
expect(onStateChange).lastCalledWith({
|
||||
index: 0,
|
||||
key: '0',
|
||||
routeNames: ['foo', 'bar'],
|
||||
routes: [
|
||||
{
|
||||
key: 'foo',
|
||||
name: 'foo',
|
||||
params: { answer: 42 },
|
||||
},
|
||||
{ key: 'bar', name: 'bar' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'test',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -144,6 +205,7 @@ it('initializes state for nested screens in React.Fragment', () => {
|
||||
expect(onStateChange).toBeCalledTimes(1);
|
||||
expect(onStateChange).toBeCalledWith({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 0,
|
||||
key: '0',
|
||||
routeNames: ['foo', 'bar', 'baz'],
|
||||
@@ -194,6 +256,7 @@ it('initializes state for nested navigator on navigation', () => {
|
||||
expect(onStateChange).toBeCalledTimes(1);
|
||||
expect(onStateChange).toBeCalledWith({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 2,
|
||||
key: '0',
|
||||
routeNames: ['foo', 'bar', 'baz'],
|
||||
@@ -205,6 +268,7 @@ it('initializes state for nested navigator on navigation', () => {
|
||||
name: 'baz',
|
||||
state: {
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 0,
|
||||
key: '1',
|
||||
routeNames: ['qux'],
|
||||
@@ -309,6 +373,7 @@ it('cleans up state when the navigator unmounts', () => {
|
||||
expect(onStateChange).toBeCalledTimes(1);
|
||||
expect(onStateChange).lastCalledWith({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 0,
|
||||
key: '0',
|
||||
routeNames: ['foo', 'bar'],
|
||||
@@ -361,6 +426,7 @@ it('allows state updates by dispatching a function returning an action', () => {
|
||||
expect(onStateChange).toBeCalledTimes(1);
|
||||
expect(onStateChange).toBeCalledWith({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 1,
|
||||
key: '0',
|
||||
routeNames: ['foo', 'bar'],
|
||||
@@ -399,6 +465,7 @@ it('updates route params with setParams', () => {
|
||||
expect(onStateChange).toBeCalledTimes(1);
|
||||
expect(onStateChange).lastCalledWith({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 0,
|
||||
key: '0',
|
||||
routeNames: ['foo', 'bar'],
|
||||
@@ -413,6 +480,7 @@ it('updates route params with setParams', () => {
|
||||
expect(onStateChange).toBeCalledTimes(2);
|
||||
expect(onStateChange).lastCalledWith({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 0,
|
||||
key: '0',
|
||||
routeNames: ['foo', 'bar'],
|
||||
@@ -470,6 +538,7 @@ it('updates route params with setParams applied to parent', () => {
|
||||
{ key: 'bar', name: 'bar' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'test',
|
||||
});
|
||||
|
||||
act(() => setParams({ age: 25 }));
|
||||
@@ -484,6 +553,7 @@ it('updates route params with setParams applied to parent', () => {
|
||||
{ key: 'bar', name: 'bar' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'test',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -516,6 +586,7 @@ it('handles change in route names', () => {
|
||||
|
||||
expect(onStateChange).toBeCalledWith({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 0,
|
||||
key: '0',
|
||||
routeNames: ['foo', 'baz', 'qux'],
|
||||
@@ -628,6 +699,7 @@ it('gives access to internal state', () => {
|
||||
routeNames: ['bar'],
|
||||
routes: [{ key: 'bar', name: 'bar' }],
|
||||
stale: false,
|
||||
type: 'test',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -216,6 +216,7 @@ it('fires blur event when a route is removed with a delay', async () => {
|
||||
|
||||
return {
|
||||
stale: false,
|
||||
type: 'test',
|
||||
key: 'stack',
|
||||
index: 0,
|
||||
routeNames,
|
||||
|
||||
@@ -76,6 +76,7 @@ it("lets parent handle the action if child didn't", () => {
|
||||
expect(onStateChange).toBeCalledTimes(1);
|
||||
expect(onStateChange).lastCalledWith({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 2,
|
||||
key: '0',
|
||||
routeNames: ['foo', 'bar', 'baz'],
|
||||
@@ -191,6 +192,7 @@ it("lets children handle the action if parent didn't", () => {
|
||||
expect(onStateChange).toBeCalledTimes(1);
|
||||
expect(onStateChange).lastCalledWith({
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 0,
|
||||
key: '0',
|
||||
routeNames: ['foo', 'bar', 'baz'],
|
||||
@@ -200,6 +202,7 @@ it("lets children handle the action if parent didn't", () => {
|
||||
name: 'baz',
|
||||
state: {
|
||||
stale: false,
|
||||
type: 'test',
|
||||
index: 0,
|
||||
key: '1',
|
||||
routeNames: ['qux', 'lex'],
|
||||
|
||||
@@ -23,6 +23,12 @@ export type NavigationState = {
|
||||
routes: Array<
|
||||
Route<string> & { state?: NavigationState | PartialState<NavigationState> }
|
||||
>;
|
||||
/**
|
||||
* Custom type for the state, whether it's for tab, stack, drawer etc.
|
||||
* During rehydration, the state will be discarded if type doesn't match with router type.
|
||||
* It can also be used to detect the type of the navigator we're dealing with.
|
||||
*/
|
||||
type: string;
|
||||
/**
|
||||
* Whether the navigation state has been rehydrated.
|
||||
*/
|
||||
@@ -36,9 +42,10 @@ export type InitialState = Partial<
|
||||
};
|
||||
|
||||
export type PartialState<State extends NavigationState> = Partial<
|
||||
Omit<State, 'stale' | 'key' | 'routes' | 'routeNames'>
|
||||
Omit<State, 'stale' | 'type' | 'key' | 'routes' | 'routeNames'>
|
||||
> & {
|
||||
stale?: true;
|
||||
type?: string;
|
||||
routes: Array<
|
||||
Omit<Route<string>, 'key'> & { key?: string; state?: InitialState }
|
||||
>;
|
||||
@@ -115,6 +122,12 @@ export type Router<
|
||||
State extends NavigationState,
|
||||
Action extends NavigationAction
|
||||
> = {
|
||||
/**
|
||||
* Type of the router. Should match the `type` property in state.
|
||||
* If the type doesn't match, the state will be discarded during rehydration.
|
||||
*/
|
||||
type: State['type'];
|
||||
|
||||
/**
|
||||
* Initialize the navigation state.
|
||||
*
|
||||
|
||||
@@ -166,6 +166,17 @@ export default function useNavigationBuilder<
|
||||
);
|
||||
}
|
||||
|
||||
const isStateValid = React.useCallback(
|
||||
state => state.type === undefined || state.type === router.type,
|
||||
[router.type]
|
||||
);
|
||||
|
||||
const isStateInitialized = React.useCallback(
|
||||
state =>
|
||||
state !== undefined && state.stale === false && isStateValid(state),
|
||||
[isStateValid]
|
||||
);
|
||||
|
||||
const {
|
||||
state: currentState,
|
||||
getState: getCurrentState,
|
||||
@@ -188,7 +199,7 @@ export default function useNavigationBuilder<
|
||||
// Otherwise assume that the state was provided as initial state
|
||||
// So we need to rehydrate it to make it usable
|
||||
initializedStateRef.current =
|
||||
currentState === undefined
|
||||
currentState === undefined || !isStateValid(currentState)
|
||||
? router.getInitialState({
|
||||
routeNames,
|
||||
routeParamList,
|
||||
@@ -207,9 +218,9 @@ export default function useNavigationBuilder<
|
||||
// If the state isn't initialized, or stale, use the state we initialized instead
|
||||
// The state won't update until there's a change needed in the state we have initalized locally
|
||||
// So it'll be `undefined` or stale untill the first navigation event happens
|
||||
currentState === undefined || currentState.stale !== false
|
||||
? (initializedStateRef.current as State)
|
||||
: (currentState as State);
|
||||
isStateInitialized(currentState)
|
||||
? (currentState as State)
|
||||
: (initializedStateRef.current as State);
|
||||
|
||||
let nextState: State = state;
|
||||
|
||||
@@ -271,10 +282,10 @@ export default function useNavigationBuilder<
|
||||
const getState = React.useCallback((): State => {
|
||||
const currentState = getCurrentState();
|
||||
|
||||
return currentState === undefined || currentState.stale !== false
|
||||
? (initializedStateRef.current as State)
|
||||
: (currentState as State);
|
||||
}, [getCurrentState]);
|
||||
return isStateInitialized(currentState)
|
||||
? (currentState as State)
|
||||
: (initializedStateRef.current as State);
|
||||
}, [getCurrentState, isStateInitialized]);
|
||||
|
||||
const emitter = useEventEmitter();
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ it('gets initial state from route names and params with initialRouteName', () =>
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,6 +53,7 @@ it('gets initial state from route names and params without initialRouteName', ()
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -85,6 +87,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
{ key: 'qux-1', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -106,6 +109,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -132,6 +136,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
{ key: 'qux-2', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -154,6 +159,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -178,6 +184,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -196,6 +203,7 @@ it("doesn't rehydrate state if it's not stale", () => {
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false as const,
|
||||
type: 'drawer' as const,
|
||||
};
|
||||
|
||||
expect(
|
||||
@@ -213,6 +221,7 @@ it('handles navigate action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -224,6 +233,7 @@ it('handles navigate action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -243,6 +253,7 @@ it('handles navigate action with open drawer', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -254,6 +265,7 @@ it('handles navigate action with open drawer', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -273,6 +285,7 @@ it('handles open drawer action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -284,6 +297,7 @@ it('handles open drawer action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -294,6 +308,7 @@ it('handles open drawer action', () => {
|
||||
|
||||
const state = {
|
||||
stale: false as const,
|
||||
type: 'drawer' as const,
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -314,6 +329,7 @@ it('handles close drawer action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -325,6 +341,7 @@ it('handles close drawer action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -335,6 +352,7 @@ it('handles close drawer action', () => {
|
||||
|
||||
const state = {
|
||||
stale: false as const,
|
||||
type: 'drawer' as const,
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -355,6 +373,7 @@ it('handles toggle drawer action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -366,6 +385,7 @@ it('handles toggle drawer action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -378,6 +398,7 @@ it('handles toggle drawer action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -389,6 +410,7 @@ it('handles toggle drawer action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -413,6 +435,7 @@ it('updates route key history on focus change', () => {
|
||||
{ key: 'qux-0', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false as const,
|
||||
type: 'drawer' as const,
|
||||
};
|
||||
|
||||
expect(router.getStateForRouteFocus(state, 'bar-0').routeKeyHistory).toEqual(
|
||||
@@ -441,6 +464,7 @@ it('closes drawer on focus change', () => {
|
||||
{ key: 'qux-0', name: 'qux' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
},
|
||||
'baz-0'
|
||||
)
|
||||
@@ -456,6 +480,7 @@ it('closes drawer on focus change', () => {
|
||||
{ key: 'qux-0', name: 'qux' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -472,6 +497,7 @@ it('closes drawer on focus change', () => {
|
||||
{ key: 'qux-0', name: 'qux' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
},
|
||||
'baz-0'
|
||||
)
|
||||
@@ -487,5 +513,6 @@ it('closes drawer on focus change', () => {
|
||||
{ key: 'qux-0', name: 'qux' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,6 +20,7 @@ it('gets initial state from route names and params with initialRouteName', () =>
|
||||
routeNames: ['bar', 'baz', 'qux'],
|
||||
routes: [{ key: 'baz-test', name: 'baz', params: { answer: 42 } }],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -40,6 +41,7 @@ it('gets initial state from route names and params without initialRouteName', ()
|
||||
routeNames: ['bar', 'baz', 'qux'],
|
||||
routes: [{ key: 'bar-test', name: 'bar' }],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -70,6 +72,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
{ key: 'qux-1', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -94,6 +97,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
{ key: 'qux-2', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -110,6 +114,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
routeNames: ['bar', 'baz', 'qux'],
|
||||
routes: [{ key: 'bar-test', name: 'bar' }],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -122,6 +127,7 @@ it("doesn't rehydrate state if it's not stale", () => {
|
||||
routeNames: ['bar', 'baz', 'qux'],
|
||||
routes: [{ key: 'bar-test', name: 'bar' }],
|
||||
stale: false as const,
|
||||
type: 'stack' as const,
|
||||
};
|
||||
|
||||
expect(
|
||||
@@ -147,6 +153,7 @@ it('gets state on route names change', () => {
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
},
|
||||
{
|
||||
routeNames: ['qux', 'baz', 'foo', 'fiz'],
|
||||
@@ -165,6 +172,7 @@ it('gets state on route names change', () => {
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -178,6 +186,7 @@ it('gets state on route names change', () => {
|
||||
{ key: 'bar-test', name: 'bar' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
},
|
||||
{
|
||||
routeNames: ['baz', 'qux'],
|
||||
@@ -192,6 +201,7 @@ it('gets state on route names change', () => {
|
||||
routeNames: ['baz', 'qux'],
|
||||
routes: [{ key: 'baz-test', name: 'baz', params: { name: 'John' } }],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -209,6 +219,7 @@ it('gets state on route names change with initialRouteName', () => {
|
||||
{ key: 'bar-test', name: 'bar' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
},
|
||||
{
|
||||
routeNames: ['baz', 'qux'],
|
||||
@@ -223,6 +234,7 @@ it('gets state on route names change with initialRouteName', () => {
|
||||
routeNames: ['baz', 'qux'],
|
||||
routes: [{ key: 'qux-test', name: 'qux' }],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -233,6 +245,7 @@ it('handles navigate action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -242,6 +255,7 @@ it('handles navigate action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 2,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -260,6 +274,7 @@ it('handles navigate action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -269,6 +284,7 @@ it('handles navigate action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -279,6 +295,7 @@ it('handles navigate action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -291,6 +308,7 @@ it('handles navigate action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -304,6 +322,7 @@ it('handles navigate action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -317,6 +336,7 @@ it('handles navigate action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -330,6 +350,7 @@ it('handles navigate action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -342,6 +363,7 @@ it('handles navigate action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -352,6 +374,7 @@ it('handles navigate action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -361,6 +384,7 @@ it('handles navigate action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 2,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -379,6 +403,7 @@ it('handles go back action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -388,6 +413,7 @@ it('handles go back action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -398,6 +424,7 @@ it('handles go back action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -415,6 +442,7 @@ it('handles pop action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 2,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -428,6 +456,7 @@ it('handles pop action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -438,6 +467,7 @@ it('handles pop action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 2,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -451,6 +481,7 @@ it('handles pop action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -461,6 +492,7 @@ it('handles pop action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 2,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -478,6 +510,7 @@ it('handles pop action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -488,6 +521,7 @@ it('handles pop action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -505,6 +539,7 @@ it('handles pop to top action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 2,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -518,6 +553,7 @@ it('handles pop to top action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -532,6 +568,7 @@ it('handles push action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 2,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -541,6 +578,7 @@ it('handles push action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 3,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -551,6 +589,7 @@ it('handles push action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: 'root',
|
||||
index: 2,
|
||||
routeNames: ['baz', 'bar', 'qux'],
|
||||
@@ -576,6 +615,7 @@ it('changes index on focus change', () => {
|
||||
{ key: 'qux-0', name: 'qux' },
|
||||
],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
},
|
||||
'baz-0'
|
||||
)
|
||||
@@ -585,6 +625,7 @@ it('changes index on focus change', () => {
|
||||
routeNames: ['bar', 'baz', 'qux'],
|
||||
routes: [{ key: 'bar-0', name: 'bar' }, { key: 'baz-0', name: 'baz' }],
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
});
|
||||
|
||||
const state = {
|
||||
@@ -593,6 +634,7 @@ it('changes index on focus change', () => {
|
||||
routeNames: ['bar', 'baz', 'qux'],
|
||||
routes: [{ key: 'bar-0', name: 'bar' }, { key: 'baz-0', name: 'baz' }],
|
||||
stale: false as const,
|
||||
type: 'stack' as const,
|
||||
};
|
||||
|
||||
expect(router.getStateForRouteFocus(state, 'qux-0')).toEqual(state);
|
||||
|
||||
@@ -25,6 +25,7 @@ it('gets initial state from route names and params with initialRouteName', () =>
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -50,6 +51,7 @@ it('gets initial state from route names and params without initialRouteName', ()
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -82,6 +84,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
{ key: 'qux-1', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -102,6 +105,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -127,6 +131,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
{ key: 'qux-2', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -148,6 +153,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
});
|
||||
|
||||
expect(
|
||||
@@ -170,6 +176,7 @@ it('gets rehydrated state from partial state', () => {
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -187,6 +194,7 @@ it("doesn't rehydrate state if it's not stale", () => {
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false as const,
|
||||
type: 'tab' as const,
|
||||
};
|
||||
|
||||
expect(
|
||||
@@ -213,6 +221,7 @@ it('gets state on route names change', () => {
|
||||
{ key: 'qux-test', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
},
|
||||
{
|
||||
routeNames: ['qux', 'baz', 'foo', 'fiz'],
|
||||
@@ -234,6 +243,7 @@ it('gets state on route names change', () => {
|
||||
{ key: 'fiz-test', name: 'fiz', params: { fruit: 'apple' } },
|
||||
],
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
});
|
||||
});
|
||||
|
||||
@@ -244,6 +254,7 @@ it('handles navigate action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -254,6 +265,7 @@ it('handles navigate action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -268,6 +280,7 @@ it('handles navigate action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -278,6 +291,7 @@ it('handles navigate action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -292,6 +306,7 @@ it('handles navigate action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -310,6 +325,7 @@ it('handles jump to action', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -320,6 +336,7 @@ it('handles jump to action', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -335,6 +352,7 @@ it('handles back action with backBehavior: history', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -345,6 +363,7 @@ it('handles back action with backBehavior: history', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -356,6 +375,7 @@ it('handles back action with backBehavior: history', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -374,6 +394,7 @@ it('handles back action with backBehavior: order', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -384,6 +405,7 @@ it('handles back action with backBehavior: order', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -395,6 +417,7 @@ it('handles back action with backBehavior: order', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -416,6 +439,7 @@ it('handles back action with backBehavior: initialRoute', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -426,6 +450,7 @@ it('handles back action with backBehavior: initialRoute', () => {
|
||||
)
|
||||
).toEqual({
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -437,6 +462,7 @@ it('handles back action with backBehavior: initialRoute', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 1,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -455,6 +481,7 @@ it('handles back action with backBehavior: none', () => {
|
||||
router.getStateForAction(
|
||||
{
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: 'root',
|
||||
index: 0,
|
||||
routeNames: ['baz', 'bar'],
|
||||
@@ -480,6 +507,7 @@ it('updates route key history on navigate and jump to', () => {
|
||||
{ key: 'qux-0', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false as const,
|
||||
type: 'tab',
|
||||
};
|
||||
|
||||
expect(state.routeKeyHistory).toEqual([]);
|
||||
@@ -534,6 +562,7 @@ it('updates route key history on focus change', () => {
|
||||
{ key: 'qux-0', name: 'qux', params: { name: 'Jane' } },
|
||||
],
|
||||
stale: false as const,
|
||||
type: 'tab' as const,
|
||||
};
|
||||
|
||||
expect(router.getStateForRouteFocus(state, 'bar-0').routeKeyHistory).toEqual(
|
||||
|
||||
@@ -17,7 +17,11 @@ export type DrawerActionType =
|
||||
|
||||
export type DrawerRouterOptions = TabRouterOptions;
|
||||
|
||||
export type DrawerNavigationState = TabNavigationState & {
|
||||
export type DrawerNavigationState = Omit<TabNavigationState, 'type'> & {
|
||||
/**
|
||||
* Type of the router, in this case, it's drawer.
|
||||
*/
|
||||
type: 'drawer';
|
||||
/**
|
||||
* Whether the drawer is open or closed.
|
||||
*/
|
||||
@@ -40,7 +44,7 @@ export const DrawerActions = {
|
||||
export default function DrawerRouter(
|
||||
options: DrawerRouterOptions
|
||||
): Router<DrawerNavigationState, DrawerActionType | CommonAction> {
|
||||
const router = TabRouter(options) as Router<
|
||||
const router = (TabRouter(options) as unknown) as Router<
|
||||
DrawerNavigationState,
|
||||
TabActionType | CommonAction
|
||||
>;
|
||||
@@ -48,6 +52,8 @@ export default function DrawerRouter(
|
||||
return {
|
||||
...router,
|
||||
|
||||
type: 'drawer',
|
||||
|
||||
getInitialState({ routeNames, routeParamList }) {
|
||||
const index =
|
||||
options.initialRouteName === undefined
|
||||
@@ -56,6 +62,7 @@ export default function DrawerRouter(
|
||||
|
||||
return {
|
||||
stale: false,
|
||||
type: 'drawer',
|
||||
key: `drawer-${shortid()}`,
|
||||
index,
|
||||
routeNames,
|
||||
@@ -81,6 +88,7 @@ export default function DrawerRouter(
|
||||
|
||||
return {
|
||||
...state,
|
||||
type: 'drawer',
|
||||
key: `drawer-${shortid()}`,
|
||||
isDrawerOpen:
|
||||
typeof partialState.isDrawerOpen === 'boolean'
|
||||
|
||||
@@ -29,7 +29,12 @@ export type StackActionType =
|
||||
|
||||
export type StackRouterOptions = DefaultRouterOptions;
|
||||
|
||||
export type StackNavigationState = NavigationState;
|
||||
export type StackNavigationState = NavigationState & {
|
||||
/**
|
||||
* Type of the router, in this case, it's stack.
|
||||
*/
|
||||
type: 'stack';
|
||||
};
|
||||
|
||||
export const StackActions = {
|
||||
push(name: string, params?: object): StackActionType {
|
||||
@@ -47,6 +52,8 @@ export default function StackRouter(options: StackRouterOptions) {
|
||||
const router: Router<StackNavigationState, CommonAction | StackActionType> = {
|
||||
...BaseRouter,
|
||||
|
||||
type: 'stack',
|
||||
|
||||
getInitialState({ routeNames, routeParamList }) {
|
||||
const initialRouteName =
|
||||
options.initialRouteName !== undefined
|
||||
@@ -55,6 +62,7 @@ export default function StackRouter(options: StackRouterOptions) {
|
||||
|
||||
return {
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: `stack-${shortid()}`,
|
||||
index: 0,
|
||||
routeNames,
|
||||
@@ -107,6 +115,7 @@ export default function StackRouter(options: StackRouterOptions) {
|
||||
|
||||
return {
|
||||
stale: false,
|
||||
type: 'stack',
|
||||
key: `stack-${shortid()}`,
|
||||
index: routes.length - 1,
|
||||
routeNames,
|
||||
|
||||
@@ -21,6 +21,10 @@ export type TabRouterOptions = DefaultRouterOptions & {
|
||||
};
|
||||
|
||||
export type TabNavigationState = NavigationState & {
|
||||
/**
|
||||
* Type of the router, in this case, it's tab.
|
||||
*/
|
||||
type: 'tab';
|
||||
/**
|
||||
* List of previously visited route keys.
|
||||
*/
|
||||
@@ -54,6 +58,8 @@ export default function TabRouter({
|
||||
const router: Router<TabNavigationState, TabActionType | CommonAction> = {
|
||||
...BaseRouter,
|
||||
|
||||
type: 'tab',
|
||||
|
||||
getInitialState({ routeNames, routeParamList }) {
|
||||
const index =
|
||||
initialRouteName === undefined
|
||||
@@ -62,6 +68,7 @@ export default function TabRouter({
|
||||
|
||||
return {
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: `tab-${shortid()}`,
|
||||
index,
|
||||
routeNames,
|
||||
@@ -121,6 +128,7 @@ export default function TabRouter({
|
||||
|
||||
return {
|
||||
stale: false,
|
||||
type: 'tab',
|
||||
key: `tab-${shortid()}`,
|
||||
index,
|
||||
routeNames,
|
||||
|
||||
Reference in New Issue
Block a user