如何避免 React Router Link 在转到动态路由之前先转到根路由“/”?

问题描述 投票:0回答:1

我想做的是使用 Reddit API 在我的项目中进行搜索流程。

  1. 用户进行搜索
  2. Web 应用程序返回包含搜索查询的 Subreddits
  3. 每个 Subreddit 组件都有一个
    Link
    ,将用户引导至动态路线:'r/:subreddit'
  4. 该路由中指定的加载程序使用
    window.location.pathname
    来收集 subreddit 的名称(例如:r/autism)并执行提取操作以返回该 subreddit 中的最新帖子。

但是,我遇到的问题是,由于某种原因,React-Router 首先将路径名更改为“/”,然后更改为“/r/:subreddit”,因此 Loader 在执行时使用路径名“/” ' 在获取时,并返回结果。

下面是三个不同文件的代码以及 Codepen 链接(如果您想查看其中的代码块)。

main.jsx

const router = createBrowserRouter(
  [
    {
      path: '/',
      element: <App />,
      errorElement: <ErrorPage />,
      children: [
        {
          errorElement: <ErrorPage />,
          children: [
            {
              index: true,
              element: <Feed />,
              loader: indexLoader,
            },
            {
              path: 'r/:subreddit/comments/:id/:title',
              element: <Post />,
              action: commentAction,
            },
            {
              path: 'news',
              element: <Feed />,
              loader: newsLoader,
            },
            {
              path: 'tech',
              element: <Feed />,
              loader: techLoader,
            },
            {
              path: 'sports',
              element: <Feed />,
              loader: sportsLoader,
            },
            {
              path: 'astronomy',
              element: <Feed />,
              loader: spaceLoader,
            },
            {
              path: 'science',
              element: <Feed />,
              loader: scienceLoader,
            },
            {
              path: 'gaming',
              element: <Feed />,
              loader: gamingLoader,
            },
            {
              path: 'r/:subreddit',
              element: <Feed />,
              loader: subredditLoader
            } 
          ]
        },
      ],
    },
  ]

Subreddit.tsx

export default function Subreddit ({ payload }) {
    useHTMLText(payload.public_description_html, payload.id);
    //const url = `https://www.reddit.com/${payload.display_name_prefixed}.json?raw.json=1`;

    return (
        <section className="subreddit">
                <img src={payload.banner_img} className="subreddit-banner" style={{
                    backgroundColor: payload.banner_background_color
                }}/>
                
                <div className="subreddit-identity">
                    <img src={payload.icon_img} className="subreddit-icon" style={{
                        backgroundColor: payload.key_color,
                        borderRadius: "50%",
                        width: 64,
                        height: 64
                    }}/>
                    <h3>{payload.display_name_prefixed}</h3>
                    <a href={`https://www.reddit.com${payload.url}`} target="_blank" className="subreddit-button"><img src={open_tab_white as unknown as string} alt="Open subreddit in another tab" aria-label="Open subreddit in another tab"/></a>
                </div>
                
                <Link to={payload.display_name_prefixed}>
                    <p id={payload.id}></p>
                    <p style={{color: "#656869", textAlign: "center"}}>{formatAmount(payload.subscribers)} members</p>
                </Link>
        </section>
    )
}

loader.ts

export async function subreddit() {
    const pathname = window.location.pathname;
    const url = `https://www.reddit.com${pathname}.json?raw.json=1`;
    const feed = await fetchHandler(url);
    const elements = redditFilter(feed);
    
    
    return {elements, url, pathname};
}

Codepen 合集

到目前为止,我尝试过在加载器内使用

setTimeout
等待一秒钟,以便路线从 '/' 更改为 '/r/:subreddit' 但它没有做任何事情,它说你要么必须返回一些东西,要么返回 null。另外,我认为这不是一个好的做法。

渲染帖子的组件称为

Feed
。这是一个纯函数,使用
useLoader()
来渲染加载器使用 fetch 返回的文章/帖子。对于这种特殊情况,情况是相同的,用户单击 Subreddit -> Subreddit 链接将用户发送到动态路由 -> 动态路由加载器在 fetch 中使用 URL 路径名并返回文章/帖子 -> Feed 使用 useLoader() 并呈现返回的数据.

话虽这么说,我也尝试在

useEffect
组件中使用
Feed
钩子,但必须有两种情况,无论
Feed
有使用
useLoader()
的东西还是没有,并使用检索到的
 进行获取window.location.pathname
。然而,我认为这给本应简单的事情增加了很多复杂性。 (也没有成功)

我唯一需要的是让加载程序立即接收路径名,而不是先获取“/”,然后获取预期的路径名。

reactjs react-router-dom
1个回答
0
投票

此示例取自取自文档。这显示了如何使用

params
参数访问加载器中的动态路径参数。

createBrowserRouter([
  {
    path: "/teams/:teamId",
    loader: ({ params }) => {
      return fakeGetTeam(params.teamId);
    },
  },
]);

作为旁注,您可能需要研究使用请求参数,如此处所述:

function loader({ request }) {
  const url = new URL(request.url);
  const searchTerm = url.searchParams.get("q");
  return searchProducts(searchTerm);
}

使用此模式时,您可以使用表单提交来使用一些查询参数将用户导航到正确的路线,例如

r/frontend?title=react
(如果您想要这样做)。

© www.soinside.com 2019 - 2024. All rights reserved.