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.
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>
);
}
}
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 ...
}
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>
This works:
static navigationOptions = ({ navigation }: NavigationScreenProps) => ({
...
})
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",
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.
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 { .... }
public static navigationOptions: NavigationScreenConfig<NavigationStackScreenOptions> =
({navigation}) => ({/* Your options... */})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With