Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6287

React Navigation: navigating to a nested Stack requires navigating to the Stack as a screen when using TS

$
0
0

Using @react-navigation (6.x) in a React Native app, I've decided to fully annotate our navigation stacks. Everything pretty much works, despite how convoluted RN makes it. The only notable exception is the one I've included below (simplified). In short: when navigating to a stack with parameters, TS complains unless I navigate to a stack inside that stack, i.e. consider the stack itself one of the sub-routes.

Let's consider a top-level StackNavigator (Main) with a single route (SubStack):

export type MainParamList = {'SubStack': NavigatorScreenParams<SubStackParamList>}const Stack = createStackNavigator<MainParamList>()export const MainStack = () => {    return (<Stack.Navigator><Stack.Screen name='SubStack' component={SubStack} /></Stack.Navigator>    )}

Note the usage of NavigatorScreenParams as explained in the docs, so that the routes inside SubStack are correctly typed when calling navigation.navigate. So far so good.

Our second-level of navigation will be SubStack, which for the purposes of this example is going to contain a single route (SubStackNestedScreen):

export type SubStackParamList = {'SubStack': {        someParam: string    }'SubStackNestedScreen': undefined}const Stack = createStackNavigator<SubStackParamList>()type Props = StackScreenProps<SubStackParamList, 'SubStackContainer'>export const SubStack = ({route}: Props) => {    // TypeScript will complain here, because someParam doesn't exist in route.params    const {someParam} = route.params    // Do something with someParam    return (<Stack.Navigator><Stack.Screen name='SubStackNestedScreen' component={SomeNestedScreen} /></Stack.Navigator>    )}

Considering the above, you'd think that someParam is defined. Well, if I navigate to SubStack the correct way, then route.params gets assigned as expected. However, to pass TS compilation, the navigation call I have to use is as follows:

navigation.navigate('MainStack', {    screen: 'SubStack',    params: {        screen: 'SubStack',        params: {            someParam: 42,        }    },})

However, the above produces a nested entity when reading route.params in SubStack:

console.log(route)// { ... params: { params: { someParam: 42 } }

That means the TS interpretation is wrong compared to reality. When navigating without deep nesting, route.params is correctly set:

navigation.navigate('MainStack', {    screen: 'SubStack',    params: {        someParam: 42,    }})
console.log(route)// { ... params: { someParam: 42 }

I know this is a tricky and long one, but I appreciate all the help. No other nested routes have given me this headache, although possibly because they don't expect any params.

Thanks a lot <3


Viewing all articles
Browse latest Browse all 6287

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>