Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add strong typing for react navigation props

I'm using typescript in my react-native project(expo).

The project uses react-navigation, so on my screens I can set navigationOptions and I have access to the prop navigation.

Now I'm trying to strongly type these so I get hints for what properties are available to set.

interface NavStateParams {
    someValue: string
}

interface Props extends NavigationScreenProps<NavStateParams> {
   color: string
}

class Screen extends React.Component<Props, any> {
    // This works fine
    static navigationOptions: NavigationStackScreenOptions = {
        title: 'ScreenTitle'
    }
    // Does not work
    static navigationOptions: NavigationStackScreenOptions = ({navigation, screenProps }) => ({
        title: navigation.state.params.someValue
    })
}

What would be the best way to handle react-navigation as props for components.

like image 908
Mellet Avatar asked Dec 21 '17 11:12

Mellet


8 Answers

Just add NavigationType to your Props, like this:

    import { StackNavigator, NavigationScreenProp } from 'react-navigation';

    export interface HomeScreenProps {
      navigation: NavigationScreenProp<any,any>
    };

    export class HomeScreen extends React.Component<HomeScreenProps, object> {

      render() {
        return (
          <View style={styles.container}>       
            <Button
              title="Go to Details"
              onPress={() => this.props.navigation.navigate('Details')}
            />
          </View>
        );
      }
    }
like image 67
Andrej Kyselica Avatar answered Nov 15 '22 08:11

Andrej Kyselica


if you are passing the navigation prop that is defined by

let navigation = useNavigation()

to a component, the best way of typing is:

import {NavigationProp, ParamListBase} from '@react-navigation/native';

navigation: NavigationProp<ParamListBase>

Update:

Here is a better approach for strong navigation typing, using the latest @react-navigation version (6.x)

full example:

import {NativeStackNavigationProp} from '@react-navigation/native-stack';

type RootStackParamList = {

   Pdp: undefined; //current screen

   PdpComments: {slug: string}; // a screen that we are 
// navigating to, in the current screen,
// that we should pass a prop named `slug` to it

   Sellers: {data: Array<string>};

   Favorites: undefined; // a screen that we are navigating to 
// in the current screen, that we don't pass any props to it
};

interface IPdpPageProps {
   navigation: NativeStackNavigationProp<RootStackParamList, 'Pdp'>;
}

// Since our screen is in the stack, we don't need to 
// use `useNavigation()` to provide the `navigation` to
// our component, we just need to read it as a prop

function Pdp({navigation}: IPdpPageProps) {
   return ...
}
like image 28
Mahdieh Shavandi Avatar answered Nov 15 '22 07:11

Mahdieh Shavandi


A minimal configuration, with version 6.x

import { NavigationProp } from "@react-navigation/native";

interface RouterProps {
    navigation: NavigationProp<any, any>;
}

<TouchableOpacity onPress={() => navigation.navigate('Home')}>
    <Text>Navigate to Home</Text>
</TouchableOpacity>
like image 8
Osama Malik Avatar answered Nov 15 '22 07:11

Osama Malik


This works:

static navigationOptions = ({ navigation }: NavigationScreenProps) => ({
  ...
})
like image 5
J. Hesters Avatar answered Nov 15 '22 09:11

J. Hesters


I think with react-navigation 5.X it's simpler now. Here is how to type hint navigation props passed to screens/components:

export default class Header extends React.Component<{
    navigation: StackNavigationHelpers;
}> {
...
}

Ps: Tested with these versions

"@react-navigation/native": "^5.2.3",
"@react-navigation/stack": "^5.3.1",
like image 5
0case Avatar answered Nov 15 '22 08:11

0case


I have same issue, and here's my solution:

import * as React from 'react'
import { NavigationScreenProps, NavigationStackScreenOptions } from 'react-navigation'

interface NavStateParams {
  someValue: string
}

// tslint:disable-next-line:no-any
type NavigationOptionsFn<TParams=any> = (props: NavigationScreenProps<TParams>) => NavigationStackScreenOptions

class Screen extends React.Component {
  // This should works fine
  static navigationOptions: NavigationOptionsFn<NavStateParams> = ({ navigation, screenProps }) => ({
    title: navigation.state.params.someValue
  })
}

You may want to declare NavigationOptionsFn<TParams> type into some d.ts file to make it work globally.

like image 4
Adiono Avatar answered Nov 15 '22 09:11

Adiono


 yarn add --dev @types/jest @types/react-navigation

import { NavigationScreenProps } from "react-navigation";

export interface ISignInProps extends NavigationScreenProps<{}> { userStore: IUserStore }

export class SignInScreen extends React.Component { .... }
like image 3
Javier González Avatar answered Nov 15 '22 09:11

Javier González


public static navigationOptions: NavigationScreenConfig<NavigationStackScreenOptions> = 
    ({navigation}) => ({/* Your options... */})
like image 2
Iwaz Avatar answered Nov 15 '22 09:11

Iwaz