From e8515f9cd94a912c107a407dea3d953c4172393f Mon Sep 17 00:00:00 2001 From: Satyajit Sahoo Date: Fri, 30 Oct 2020 13:26:52 +0100 Subject: [PATCH] fix: fix params from for the root screen when creating action closes #9006 --- .../src/__tests__/getActionFromState.test.tsx | 50 +++++++++++++++++++ packages/core/src/getActionFromState.tsx | 38 +++++++++----- 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/packages/core/src/__tests__/getActionFromState.test.tsx b/packages/core/src/__tests__/getActionFromState.test.tsx index 7f52c572..ed98c81e 100644 --- a/packages/core/src/__tests__/getActionFromState.test.tsx +++ b/packages/core/src/__tests__/getActionFromState.test.tsx @@ -45,6 +45,25 @@ it('gets navigate action from state', () => { }); }); +it('gets navigate action from state for top-level screen', () => { + const state = { + routes: [ + { + name: 'foo', + params: { answer: 42 }, + }, + ], + }; + + expect(getActionFromState(state)).toEqual({ + payload: { + name: 'foo', + params: { answer: 42 }, + }, + type: 'NAVIGATE', + }); +}); + it('gets navigate action from state with 2 screens', () => { const state = { routes: [ @@ -205,6 +224,37 @@ it('gets navigate action from state with config', () => { }); }); +it('gets navigate action from state for top-level screen with config', () => { + const state = { + routes: [ + { + name: 'foo', + params: { answer: 42 }, + }, + ], + }; + + const config = { + screens: { + initialRouteName: 'bar', + foo: { + path: 'some-path/:answer', + parse: { + answer: Number, + }, + }, + }, + }; + + expect(getActionFromState(state, config)).toEqual({ + payload: { + name: 'foo', + params: { answer: 42 }, + }, + type: 'NAVIGATE', + }); +}); + it('gets navigate action from state with 2 screens including initial route and with config', () => { const state = { routes: [ diff --git a/packages/core/src/getActionFromState.tsx b/packages/core/src/getActionFromState.tsx index c8307282..a3a2d07c 100644 --- a/packages/core/src/getActionFromState.tsx +++ b/packages/core/src/getActionFromState.tsx @@ -3,6 +3,7 @@ import type { PartialRoute, NavigationState, PartialState, + CommonActions, } from '@react-navigation/routers'; import type { PathConfig, PathConfigMap, NestedNavigateParams } from './types'; @@ -24,14 +25,34 @@ type NavigateAction = { export default function getActionFromState( state: PartialState, options?: Options -): NavigateAction | undefined { +): NavigateAction | CommonActions.Action | undefined { // Create a normalized configs object which will be easier to use const normalizedConfig = options ? createNormalizedConfigItem(options) : {}; - let payload; - let current: PartialState | undefined = state; - let config: ConfigItem | undefined = normalizedConfig; - let params: NestedNavigateParams = {}; + if (state.routes.length === 0) { + return undefined; + } + + if ( + !( + state.routes.length === 1 || + (state.routes.length === 2 && + state.routes[0].name === normalizedConfig?.initialRouteName) + ) + ) { + return { + type: 'RESET', + payload: state, + }; + } + + const route = state.routes[state.index ?? state.routes.length - 1]; + + let current: PartialState | undefined = route?.state; + let config: ConfigItem | undefined = normalizedConfig?.screens?.[route?.name]; + let params: NestedNavigateParams = { ...route.params }; + + let payload = route ? { name: route.name, params } : undefined; while (current) { if (current.routes.length === 0) { @@ -70,13 +91,6 @@ export default function getActionFromState( current = route.state; config = config?.screens?.[route.name]; - - if (!payload) { - payload = { - name: route.name, - params, - }; - } } if (!payload) {