📌

React Navigationのnavigateとrouteの型定義

2022/11/20に公開

navigator を作るときにやること

navigator を作るときに、ルートの名前と引数の型を定義するには、まず初めにルートの名前とそのルートの引数の型の対応表となるオブジェクトを作ります。

// typeで作ること。interfaceではダメらしい
// 参考:https://reactnavigation.org/docs/typescript/#annotating-usenavigation
type RootStackParamList = {
  Home: undefined; // Homeには引数が必要ない
  Profile: { userId: string };
  Feed: { sort: "latest" | "top" } | undefined; // Feedには引数があったら{ sort: "latest" | "top" }型で、無くてもOK
};

対応表となるオブジェクトを作ったらそれを使って実際にnavigatorを作ります:

import { createStackNavigator } from "@react-navigation/stack";

const RootStack = createStackNavigator<RootStackParamList>();

そして以下のように使います:

<RootStack.Navigator initialRouteName="Home">
  <RootStack.Screen name="Home" component={Home} />
  <RootStack.Screen
    name="Profile"
    component={Profile}
    initialParams={{ userId: user.id }}
  />
  <RootStack.Screen name="Feed" component={Feed} />
</RootStack.Navigator>

screen を作るときにやること

screen を作るときに、先ほど定義したルートごとの型定義を反映させるにはnavigator毎に便利な型があります。

例えばStackNavigatorに対しては、以下のようにします:

import type { NativeStackScrennProps } from "@react-navigation/native-stack";

type RootStackParamList = {
  Home: undefined;
  Profile: { userId: string };
  Feed: { sort: "latest" | "top" } | undefined;
};

type Props = NativeStackScrennProps<RootStackParamList, "Profile">;

NativeStackScrennPropsはジェネリックスで以下の 3 つを引数にとります:

  1. 先ほど定義したルートごとの引数の型の対応表となるオブジェクト(ここではRootStackParamList)
  2. スクリーンが属するルートの名前(ここではProfile)
  3. (任意)navigatorの ID(多分あまり使わない、ここでいう ID とは恐らくこれ)

StackNavigator以外の場合では以下のような型が用意されています:

  • StackSceenProps(@react-navigation/stack用)
  • DrawerSceenProps(@react-navigation/drawer用)
  • BottomTabScreenProps(@react-navigation/bottom-tabs用)

関数コンポーネントでは:

function ProfileScreen({ route, navigation }: Props) {
  // ...
}

const ProfileScreen: React.FC<Props> = ({ route, navigation }) => {
  // ...
};

クラスコンポーネントでは:

class ProfileScreen extends React.Component<Props> {
  render() {
    // ...
  }
}

route と navigation に対する型付けをそれぞれ行う

routenavigationに対する型付けをそれぞれ行うこともできます。
このときも便利な型が用意されていて、例えばnavigationだけなら以下のような感じ:

import type { NativeStackNavigationProps } from "@react-navigation/native-stack";

type ProfileScreenNavigationProp = NativeStackNavigationProps<
  RootStackParamList,
  "Profile"
>;

routeだけなら以下のような感じ:

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

type ProfileScreenRouteProp = RouteProp<RootStackParamList, "Profile">;

参考

https://reactnavigation.org/docs/typescript/

Discussion