Добавить сильную типизацию для реагирования на навигационные опоры
Я использую typescript в своем проекте, посвященном реакции (expo).
В проекте используется интерактивная навигация, поэтому на моих экранах я могу установить navigationOptions
, и у меня есть доступ к prop navigation
.
Теперь я пытаюсь сильно набрать их, чтобы получить подсказки о том, какие свойства доступны для установки.
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
})
}
Каким будет лучший способ обработки реакции-навигации в качестве реквизита для компонентов.
Ответы
Ответ 1
Просто добавьте NavigationType к своим реквизитам, например:
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>
);
}
}
Ответ 2
Это работает:
static navigationOptions = ({ navigation }: NavigationScreenProps) => ({
...
})
Ответ 3
У меня такая же проблема, и вот мое решение:
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
})
}
Вы можете захотеть объявить тип NavigationOptionsFn<TParams>
в некоторый файл d.ts
, чтобы он работал глобально.
Ответ 4
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 { .... }
Ответ 5
public static navigationOptions: NavigationScreenConfig<NavigationStackScreenOptions> =
({navigation}) => ({/* Your options... */})
Ответ 6
Вместо того, чтобы описывать вручную все ваши функции навигации (например: навигация), в интерфейсе вашего Props вы можете напрямую расширять NavigationScreenProp
.
В моем случае это было обязательным, чтобы остановить eslint от выдачи ошибки.
import { StackNavigator, NavigationScreenProp } from 'react-navigation';
export interface HomeScreenProps extends NavigationScreenProp {
/* your custom props here */
};
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>
);
}
}
Ответ 7
Это похоже на работу:
public static navigationOptions: NavigationScreenOptionsGetter<
NavigationScreenOptions
> = (navigation, stateProps) => ({
title: navigation.state.params.someValue,
});
Ответ 8
Раздел does not work
содержит ошибку, если ваш tsconfig.json
имеет "strictNullChecks": true
. В этом случае у вас действительно есть ошибка, потому что в строке
navigation.state.params.someValue
params
является обязательным. Что вы можете сделать, это проверить, передано ли значение внутрь, и указать значение по умолчанию, например:
title: navigation.state.params && navigation.state.params.someValue || 'Default title'
Ответ 9
Если кто-то все еще испытывает эту проблему при расширении NavigationScreenProps
, чтобы вы могли правильно ввести navigationOptions
и т.д. Вместе со своими реквизитами:
interface Props extends NavigationScreenProps {
someProp: string;
anotherProp: string;
}
export const SomeGreatScreen: NavigationScreenComponent<NavigationParams, {}, Props> = ({
someProp,
anotherProp,
}) => {
...
};
Принимая во внимание, что NavigationScreenComponent<Props>
приводил к ошибкам типа для деструктурированных свойств { someProp, anotherProp }
, не распознавая расширение реквизита, NavigationScreenComponent<NavigationParams, {}, Props>
делал. По-видимому, это связано с необходимостью отправки расширенного типа реквизита в качестве третьего параметра:
export type NavigationScreenComponent<
Params = NavigationParams,
Options = {},
Props = {}
> = React.ComponentType<NavigationScreenProps<Params, Options> & Props> & {
navigationOptions?: NavigationScreenConfig<Options>;
};
from react-navigation.d.ts