React Native Navigation 的动态查询参数是否等效?

Equivalent of dynamic query params for React Native Navigation?

我想在 React Native 中根据 userId 动态显示配置文件。在我设置路线的地方做出反应,我会添加类似 route="/users/:userId" 的内容,然后使用该 userId 进行各种调用,显示各种数据等。当我在配置文件页面上实现 link 时, 我将它们路由到 /users/1.

如何在 React Native 中实现类似的功能?在网络上看到的唯一一件事就是将它作为参数传递,但这是否意味着我每次调用 navigation.navigate 时都必须传递它?我不确定 route-defining 或 navigation.navigate 语法应该是什么样子。

我检查了 a couple of SO threads, but none of them seem to answer this fundamental question. And all of the docs and articles 关于 React Navigation 中的动态路由似乎主要关注传递动态标题 headers 和东西。

React Navigation 主要使用看起来像 { userId: 1 } 的参数对象,而不是像 "/users/:userId".

这样的基于字符串的路由定义

链接到配置文件

navigation.navigate function需要两个道具:路线的name和要通过的params。如果您导航到不带任何参数的路由,则根本不需要包含第二个 params 参数。 navigation.navigate("Home") 没问题。但是当转到你的“用户”路线时,你 总是 需要包含一个 userId.

为了转到特定的用户配置文件,您可以调用:

onPress={() => navigation.navigate("User", { userId: 1 })}

文档:Passing parameters to routes

访问参数

然后可以通过导航器注入的道具在 UserScreen 组件中访问 userId 参数。每个屏幕都会收到道具 route and navigateparamsroute 属性的 属性。

所以你可以像这样定义一个 UserRoute 组件,我们从 route.params.userId.

得到当前的 userId
const UserScreen = ({route, navigation}) => (
  <View>
    <Text>Viewing profile for user #{route.params.userId}</Text>
    <TouchableOpacity onPress={() => navigation.navigate("Home")}>
      <Text>Back to Home</Text>
    </TouchableOpacity>
  </View>
);

(Typescript 用户:此组件是 React.FC<StackScreenProps<RootStackParamList, "User">>,其中 RootStackParamList 是您自己的应用程序的参数定义)

声明路由

在创建路由时,您实际上不需要说明任何有关参数的信息。这很好用:

export const App = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="User" component={UserScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

您可以使用一些额外的可选配置。例如,您可以map the params to options or map the params to a unique screen id

<Stack.Screen
  name="User"
  component={UserScreen}
  options={({ route }) => ({
    title: `User Profile #${route.params.userId}`
  })}
  getId={({ params }) => params.userId.toString()}
/>

(Typescript 用户会想要定义一个类型,通常称为 RootStackParamList,它将每个路由映射到它的参数类型。然后将其用作 StackScreenPropsStackNavigationProp, 等等)

基于字符串的导航

React Navigation 支持 link 到像 "/user/1" 这样的路径,但它需要额外的配置。在幕后它仍然使用 params 对象,因此您需要 define a mapping 从路径到 params。它可以是自定义映射,或者您可以使用与 React Router 相同的语法 : 来定义参数。 "users/:userId" 将创建一个以 userId 作为键的参数对象。

您的 Stack.Screen 组件保持不变。配置选项作为道具 linking 传递给 NavigationContainer 组件。如果你设置了它,那么你就可以像在 React Router 中那样使用实验性的 Link component 到 link 到像 "/users/1".

这样的路径
export const App = () => {
  return (
    <NavigationContainer
      linking={{
        prefixes: ["https://yourdomain.com"],
        config: {
          screens: {
            Home: "",
            User: "users/:userId"
          }
        }
      }}
    >
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="User" component={UserScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

CodeSandbox Demo 打字稿类型。