首页 > 解决方案 > 等效于 React Native Navigation 的动态查询参数?

问题描述

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

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

我检查了几个SO 线程,但似乎没有一个能回答这个基本问题。并且所有关于 React Navigation 中动态路由的文档和文章似乎都主要关注动态标题标题和内容的传递。

标签: reactjsreact-nativereact-navigation

解决方案


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

链接到个人资料

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

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

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

文档:将参数传递给路由

访问参数

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

所以你可以UserRoute像这样定义一个组件,我们从中获取userId电流route.params.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>
);

(打字稿用户:这个组件是您自己的应用程序的参数定义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>
  );
};

您可以使用一些额外的可选配置。例如,您可以将参数映射到选项将参数映射到唯一的屏幕 id

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

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

基于字符串的导航

React Navigation确实支持链接到类似 的路径"/user/1",但它需要额外的配置。在幕后它仍然使用 params 对象,因此您需要定义从路径到 params 的映射。它可以是自定义映射,也可以使用与 React Router 相同的语法:来定义参数。 "users/:userId"将创建一个以userId为键的 params 对象。

您的Stack.Screen组件保持不变。配置选项作为道具传递linkingNavigationContainer组件。如果你设置了这个,那么你就可以像在 React Router 中一样使用实验性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>
  );
};

带有 typescript 类型的CodeSandbox Demo


推荐阅读