【问题标题】:Hide route params from the url with react-navigation使用 react-navigation 隐藏 url 中的路由参数
【发布时间】:2020-10-28 09:37:00
【问题描述】:

我正在将 ReactNative 移动应用程序改编为 ReactNative Web。该应用程序使用react-navigation 完成。

目前,每次我设置路由的参数(通过navigatesetParams)时,这些参数都会显示在 URL 中。我最终得到了看起来很糟糕的 URL,如下所示: http://localhost:19006/me/undefined?user=%5Bobject%20Object%5D

该网址或网址包含与用户无关的数据,通常看起来很混乱。

有没有办法不在 URL 中显示路由参数?

【问题讨论】:

    标签: react-native react-navigation react-native-web


    【解决方案1】:

    如果您不希望在 URL 中使用这些数据,您应该重新考虑 params 是否是存放此数据的合适位置。您认为该 URL 包含不相关的数据表明该数据不属于导航状态。

    如果您直接从 URL 访问屏幕,它应该呈现与您以编程方式导航到它时相同的效果。如果您在 params 中传递某些内容,则意味着屏幕正确呈现需要该信息,如果您将其从 URL 中删除,则该信息将丢失。考虑到可以直接从 URL 打开页面,无论是在 Web 上还是通过深层链接。如果所需的数据不可用,那么它将无法正常工作。

    在您的情况下,您似乎正在传递一个完整的用户对象(也许不是,没有代码很难说)。理想情况下,这个对象应该在你的全局存储而不是 params 中,并且你应该只在 params 中传递用户 ID。然后,您应该使用该 ID 从全局存储中获取完整对象,或者如果尚未获取对象(如果需要)则触发数据获取。

    您没有在问题中指定 React Navigation 的版本。在 v5 中,您可以自定义如何将参数字符串化为 URL,以及如何使用 stringifyparse 选项将它们解析回来:

    const linking = {
      screens: {
        Profile: {
          path: 'user/:id',
          parse: {
            id: (id) => id.replace(/^@/, '')
          },
          stringify: {
            id: (id) => `@{id}`,
          },
        },
      },
    };
    

    这应该可以帮助您使 URL 看起来更漂亮,并处理参数不是简单字符串的情况。但是,您不能完全忽略 URL 中的参数,因为它们是屏幕呈现所必需的数据。

    更多详情:https://reactnavigation.org/docs/configuring-links#passing-params

    【讨论】:

    • 我明白你的意思,在大多数情况下我会尝试改变它,谢谢。但是,有时我需要使用navigate 将数据发送回上一个屏幕。这就是我仍然称之为无关数据的东西。它仅与当前会话有关,不应在页面刷新时再次发送。
    • @RyanPergent 即使对于这种情况,数据也不是无关紧要的。假设用户刷新了页面,或者 Ctrl+单击/Cmd+单击了按钮以在新选项卡中打开。 URL 中的数据意味着它在这两种情况下都会按预期工作。
    • 假设我有一个名为 ProfileStack 的堆栈,它以 userId 作为参数。我希望此堆栈中的每个屏幕都可以访问此 userId,因此我使用initialParams 将其传递下去。对于用户 78,我希望我的 URL 为 profile/78/some-menu(每个屏幕的 some-menu 都在变化)。问题是它最终变成了profile/78/some-menu?userId=78...这完全无关紧要,因为在 URL 中没有“?userId=78”,我仍然可以在重新加载时显示相同的页面,不是吗?不知道如何处理这种情况。
    • 好吧,没关系。我不确定它是如何工作的,但如果它们是堆栈 path 配置的一部分,react-navigation 似乎不会在 URL 的末尾添加 initialParams。我找不到解释规则的文档。这绝对不错,但我很想知道它的局限性。
    • 它不应该做profile/78/some-menu?userId=78,不管它们是否是初始参数。如果查询参数已经是路径的一部分,则不会添加它。 (reactnavigation.org/docs/configuring-links#passing-params) 你能打开一个关于何时看到重复发生的问题吗?这听起来像一个错误。
    【解决方案2】:

    satya164's answer 绝对是正确的路径。只是想也发布此解决方案,因为它是对问题的直接回答,即使不是最可取的。

    import { getPathFromState} from "@react-navigation/native";
    
    const linking = {
      screens: {
        ...
      },
      getPathFromState(state, config){
         let path = getPathFromState(state, config);
         const index = path.indexOf("?")
         if(index>=0){
            path = path.substr(0, index);
         }
         return path;
      }
    };
    

    【讨论】:

      【解决方案3】:

      注意:要使用此解决方案,您需要确保每个对象和函数参数都是可选的,否则如果您重新加载页面会出错。

      我从 url 中删除了每个对象和函数,将这个自定义 getPathFromState 添加到 linkingOptions:

      const linking = {
        config: {
          screens: {
            ...
          }
        },
        getPathFromState: (state, options) => {
          const cleanState = {
            ...state,
            routes: state.routes.map(route => {
              if(!route.params) {
                return route
              }
      
              const cleanParams = {}
              for(const param in route.params) {
                const value = route.params[param]
                if(typeof value !== "object" && typeof value !== "function") {
                  cleanParams[param] = value
                }
              }
              return {
                ...route,
                params: cleanParams,
              }
            }),
          }
          return getPathFromState(cleanState, options) //imported from @react-navigation/native
        },
      }
      

      【讨论】:

        【解决方案4】:

        您可以将组件所需的参数作为道具传递

        喜欢这个

        navigation.navigate('Details', {
             itemId: 86,
             otherParam: 'anything you want here',
             });
        

        然后在细节组件中

        const { itemId , otherParam} = route.params;
        

        或者,如果您使用 Redux/Mobx 或任何其他全局状态管理

        您可以从那里提取数据,而不是通过 URL 传递数据 然后通过connectuseSelector hooks 获取数据

        【讨论】:

        • 我的问题可能不够清楚。我知道如何发送参数,我按照你的描述做。我的问题是这些参数显示在我导航到的页面上的 URL 中。我希望它们不在 URL 中显示。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-23
        • 1970-01-01
        • 2022-01-17
        相关资源
        最近更新 更多