Skip to content

Commit

Permalink
fix(useNavigationBuilder): React to initialRouteName changes just lik…
Browse files Browse the repository at this point in the history
…e to routes changes
  • Loading branch information
jtomaszewski committed Jun 17, 2020
1 parent e20caca commit 8a4a46e
Show file tree
Hide file tree
Showing 15 changed files with 172 additions and 118 deletions.
10 changes: 3 additions & 7 deletions packages/core/src/__tests__/BaseNavigationContainer.test.tsx
@@ -1,10 +1,6 @@
import * as React from 'react';
import { act, render } from 'react-native-testing-library';
import {
DefaultRouterOptions,
NavigationState,
Router,
} from '@react-navigation/routers';
import { NavigationState, Router } from '@react-navigation/routers';
import BaseNavigationContainer from '../BaseNavigationContainer';
import NavigationStateContext from '../NavigationStateContext';
import MockRouter, { MockActions } from './__fixtures__/MockRouter';
Expand Down Expand Up @@ -79,8 +75,8 @@ it('throws when nesting containers', () => {
it('handle dispatching with ref', () => {
const CurrentParentRouter = MockRouter;

function CurrentChildRouter(options: DefaultRouterOptions) {
const CurrentMockRouter = MockRouter(options);
function CurrentChildRouter() {
const CurrentMockRouter = MockRouter();
const ChildRouter: Router<
NavigationState,
MockActions | { type: 'REVERSE' }
Expand Down
9 changes: 4 additions & 5 deletions packages/core/src/__tests__/__fixtures__/MockRouter.tsx
Expand Up @@ -4,22 +4,21 @@ import {
CommonNavigationAction,
NavigationState,
Route,
DefaultRouterOptions,
} from '@react-navigation/routers';

export type MockActions = CommonNavigationAction | { type: 'NOOP' | 'UPDATE' };

export const MockRouterKey = { current: 0 };

export default function MockRouter(options: DefaultRouterOptions) {
export default function MockRouter() {
const router: Router<NavigationState, MockActions> = {
type: 'test',

getInitialState({ routeNames, routeParamList }) {
getInitialState({ initialRouteName, routeNames, routeParamList }) {
const index =
options.initialRouteName === undefined
initialRouteName === undefined
? 0
: routeNames.indexOf(options.initialRouteName);
: routeNames.indexOf(initialRouteName);

return {
stale: false,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/__tests__/index.test.tsx
Expand Up @@ -742,8 +742,8 @@ it('navigates to nested child in a navigator', () => {
});

it('navigates to nested child in a navigator with initial: false', () => {
const TestRouter: typeof MockRouter = (options) => {
const router = MockRouter(options);
const TestRouter: typeof MockRouter = () => {
const router = MockRouter();

return {
...router,
Expand Down
18 changes: 7 additions & 11 deletions packages/core/src/__tests__/useDescriptors.test.tsx
@@ -1,10 +1,6 @@
import * as React from 'react';
import { render, act } from 'react-native-testing-library';
import {
DefaultRouterOptions,
NavigationState,
Router,
} from '@react-navigation/routers';
import { NavigationState, Router } from '@react-navigation/routers';
import useNavigationBuilder from '../useNavigationBuilder';
import BaseNavigationContainer from '../BaseNavigationContainer';
import Screen from '../Screen';
Expand Down Expand Up @@ -420,8 +416,8 @@ it("returns correct value for canGoBack when it's not overridden", () => {
});

it(`returns false for canGoBack when current router doesn't handle GO_BACK`, () => {
function TestRouter(options: DefaultRouterOptions) {
const CurrentMockRouter = MockRouter(options);
function TestRouter() {
const CurrentMockRouter = MockRouter();
const ChildRouter: Router<NavigationState, MockActions> = {
...CurrentMockRouter,

Expand Down Expand Up @@ -471,8 +467,8 @@ it(`returns false for canGoBack when current router doesn't handle GO_BACK`, ()
});

it('returns true for canGoBack when current router handles GO_BACK', () => {
function ParentRouter(options: DefaultRouterOptions) {
const CurrentMockRouter = MockRouter(options);
function ParentRouter() {
const CurrentMockRouter = MockRouter();
const ChildRouter: Router<NavigationState, MockActions> = {
...CurrentMockRouter,

Expand Down Expand Up @@ -538,8 +534,8 @@ it('returns true for canGoBack when current router handles GO_BACK', () => {
});

it('returns true for canGoBack when parent router handles GO_BACK', () => {
function OverrodeRouter(options: DefaultRouterOptions) {
const CurrentMockRouter = MockRouter(options);
function OverrodeRouter() {
const CurrentMockRouter = MockRouter();
const ChildRouter: Router<NavigationState, MockActions> = {
...CurrentMockRouter,

Expand Down
14 changes: 8 additions & 6 deletions packages/core/src/__tests__/useEventEmitter.test.tsx
Expand Up @@ -296,17 +296,19 @@ it('fires focus and blur events in nested navigator', () => {
});

it('fires blur event when a route is removed with a delay', async () => {
const TestRouter = (options: any): Router<NavigationState, any> => {
const router = MockRouter(options);
const TestRouter = (): Router<NavigationState, any> => {
const router = MockRouter();

return {
...router,

getInitialState({ routeNames, routeParamList }) {
getInitialState({
initialRouteName: _initialRouteName,
routeNames,
routeParamList,
}) {
const initialRouteName =
options.initialRouteName !== undefined
? options.initialRouteName
: routeNames[0];
_initialRouteName !== undefined ? _initialRouteName : routeNames[0];

return {
stale: false,
Expand Down
8 changes: 3 additions & 5 deletions packages/core/src/__tests__/useNavigationCache.test.tsx
Expand Up @@ -27,7 +27,7 @@ it('preserves reference for navigation objects', () => {
const getState = () => state;
const navigation = {} as any;
const setOptions = (() => {}) as any;
const router = MockRouter({});
const router = MockRouter();

const Test = () => {
const previous = React.useRef<any>();
Expand Down Expand Up @@ -101,10 +101,8 @@ it('returns correct value for isFocused', () => {
});

it('returns correct value for isFocused after changing screens', () => {
const TestRouter = (
options: Parameters<typeof MockRouter>[0]
): ReturnType<typeof MockRouter> => {
const router = MockRouter(options);
const TestRouter = (): ReturnType<typeof MockRouter> => {
const router = MockRouter();

return {
...router,
Expand Down
18 changes: 7 additions & 11 deletions packages/core/src/__tests__/useOnAction.test.tsx
@@ -1,10 +1,6 @@
import * as React from 'react';
import { render } from 'react-native-testing-library';
import {
Router,
DefaultRouterOptions,
NavigationState,
} from '@react-navigation/routers';
import { Router, NavigationState } from '@react-navigation/routers';
import useNavigationBuilder from '../useNavigationBuilder';
import BaseNavigationContainer from '../BaseNavigationContainer';
import Screen from '../Screen';
Expand All @@ -16,8 +12,8 @@ import MockRouter, {
beforeEach(() => (MockRouterKey.current = 0));

it("lets parent handle the action if child didn't", () => {
function CurrentRouter(options: DefaultRouterOptions) {
const CurrentMockRouter = MockRouter(options);
function CurrentRouter() {
const CurrentMockRouter = MockRouter();
const ParentRouter: Router<
NavigationState,
MockActions | { type: 'REVERSE' }
Expand Down Expand Up @@ -95,8 +91,8 @@ it("lets parent handle the action if child didn't", () => {
it("lets children handle the action if parent didn't", () => {
const CurrentParentRouter = MockRouter;

function CurrentChildRouter(options: DefaultRouterOptions) {
const CurrentMockRouter = MockRouter(options);
function CurrentChildRouter() {
const CurrentMockRouter = MockRouter();
const ChildRouter: Router<
NavigationState,
MockActions | { type: 'REVERSE' }
Expand Down Expand Up @@ -227,8 +223,8 @@ it("lets children handle the action if parent didn't", () => {
it("action doesn't bubble if target is specified", () => {
const CurrentParentRouter = MockRouter;

function CurrentChildRouter(options: DefaultRouterOptions) {
const CurrentMockRouter = MockRouter(options);
function CurrentChildRouter() {
const CurrentMockRouter = MockRouter();
const ChildRouter: Router<
NavigationState,
MockActions | { type: 'REVERSE' }
Expand Down
24 changes: 16 additions & 8 deletions packages/core/src/useNavigationBuilder.tsx
Expand Up @@ -179,17 +179,20 @@ export default function useNavigationBuilder<
}, [route]);

const { children, ...rest } = options;
const routerOptions = {
...((rest as unknown) as RouterOptions),
...(route?.params &&
route.params.initial !== false &&
typeof route.params.screen === 'string'
? { initialRouteName: route.params.screen }
: null),
};
const { current: router } = React.useRef<Router<State, any>>(
createRouter({
...((rest as unknown) as RouterOptions),
...(route?.params &&
route.params.initial !== false &&
typeof route.params.screen === 'string'
? { initialRouteName: route.params.screen }
: null),
})
createRouter(routerOptions)
);

const { initialRouteName } = routerOptions;

const routeConfigs = getRouteConfigsFromChildren<
State,
ScreenOptions,
Expand Down Expand Up @@ -267,6 +270,7 @@ export default function useNavigationBuilder<
if (currentState === undefined || !isStateValid(currentState)) {
return [
router.getInitialState({
initialRouteName,
routeNames,
routeParamList,
}),
Expand All @@ -275,6 +279,7 @@ export default function useNavigationBuilder<
} else {
return [
router.getRehydratedState(currentState as PartialState<State>, {
initialRouteName,
routeNames,
routeParamList,
}),
Expand Down Expand Up @@ -303,6 +308,7 @@ export default function useNavigationBuilder<
if (!isArrayEqual(state.routeNames, routeNames)) {
// When the list of route names change, the router should handle it to remove invalid routes
nextState = router.getStateForRouteNamesChange(state, {
initialRouteName,
routeNames,
routeParamList,
});
Expand All @@ -327,6 +333,7 @@ export default function useNavigationBuilder<
nextState =
updatedState !== null
? router.getRehydratedState(updatedState, {
initialRouteName,
routeNames,
routeParamList,
})
Expand Down Expand Up @@ -448,6 +455,7 @@ export default function useNavigationBuilder<
key: route?.key,
listeners: actionListeners,
routerConfigOptions: {
initialRouteName,
routeNames,
routeParamList,
},
Expand Down
19 changes: 8 additions & 11 deletions packages/routers/src/DrawerRouter.tsx
Expand Up @@ -100,7 +100,7 @@ const closeDrawer = (state: DrawerNavigationState): DrawerNavigationState => {
export default function DrawerRouter({
openByDefault,
...rest
}: DrawerRouterOptions): Router<
}: DrawerRouterOptions = {}): Router<
DrawerNavigationState,
DrawerActionType | CommonNavigationAction
> {
Expand All @@ -114,8 +114,8 @@ export default function DrawerRouter({

type: 'drawer',

getInitialState({ routeNames, routeParamList }) {
let state = router.getInitialState({ routeNames, routeParamList });
getInitialState(configOptions) {
let state = router.getInitialState(configOptions);

if (openByDefault) {
state = openDrawer(state);
Expand All @@ -129,15 +129,12 @@ export default function DrawerRouter({
};
},

getRehydratedState(partialState, { routeNames, routeParamList }) {
getRehydratedState(partialState, configOptions) {
if (partialState.stale === false) {
return partialState;
}

let state = router.getRehydratedState(partialState, {
routeNames,
routeParamList,
});
let state = router.getRehydratedState(partialState, configOptions);

if (isDrawerOpen(partialState)) {
state = openDrawer(state);
Expand All @@ -160,7 +157,7 @@ export default function DrawerRouter({
return closeDrawer(result);
},

getStateForAction(state, action, options) {
getStateForAction(state, action, configOptions) {
switch (action.type) {
case 'OPEN_DRAWER':
return openDrawer(state);
Expand All @@ -186,10 +183,10 @@ export default function DrawerRouter({
}
}

return router.getStateForAction(state, action, options);
return router.getStateForAction(state, action, configOptions);

default:
return router.getStateForAction(state, action, options);
return router.getStateForAction(state, action, configOptions);
}
},

Expand Down

0 comments on commit 8a4a46e

Please sign in to comment.