React router v6 测试库导航相对失败

发布于 01-16 05:48 字数 1431 浏览 6 评论 0原文

在我的应用程序中,我使用 React Router v6 的相对导航(我们目前正在迁移)并且它工作正常。

当我尝试使用 Jest 和测试库进行一些测试时,相对导航失败并始终使用路径名“/”进行解析。

我使用这个包装器来渲染正在测试的组件,以将其添加为路由器。

const WrapTestComponentInRouter = (TestComponent, initialRoute = '/', history =['/']) => {
  function WrappedComponent(props) {
    return (
      <MemoryRouter initialEntries={history}>
        <Routes>
          <Route path={initialRoute} element={<TestComponent {...props} />} />
          <Route path="*" element={<Location />} />
        </Routes>
      </MemoryRouter>
    );
  }

  return WrappedComponent;
};

function ComponentToTest() {
  const location = useLocation();
  console.log(location);
  const path = useResolvedPath('..');
  console.log(path);
  return <button onClick={() => navigate('..')}>navigate</div>;
}

我使用钩子 useResolvedPath 来计算导航结果并记录它。在我的应用程序中,计算的相对路径是正确的,但在我的测试中,无论当前位置是什么,它始终等于“/”。

有人遇到并解决了这个问题吗?

编辑

好的,我明白问题是什么。 useResolvedPath 使用routingContext 来计算相对路由,因此如果我们使用“..”,它将弹出到路由树中的上一个路由。

这样,如果我想测试我的导航,我需要重现我的路线树。另一个解决方案是通过使用方法resolvePath('..', location)来使用真实的相对路径。resolvePath

从路径计算相对路径,

resolvePath('..', '/user/project') ---> '/user'

导航函数也使用RoutingContext,所以如果我想从当前路径进行相对路径我必须做

const location = useLocation();
navigate(resolvePath('..', location.pathname));

In my application i use relative navigation with react router v6 (we are currently migrating) and it works fine.

When i try to do some tests using Jest and testing-library the relative navigation fails and always resolve with the pathname '/'.

I use this wrapper to render my component under test to add it a Router.

const WrapTestComponentInRouter = (TestComponent, initialRoute = '/', history =['/']) => {
  function WrappedComponent(props) {
    return (
      <MemoryRouter initialEntries={history}>
        <Routes>
          <Route path={initialRoute} element={<TestComponent {...props} />} />
          <Route path="*" element={<Location />} />
        </Routes>
      </MemoryRouter>
    );
  }

  return WrappedComponent;
};

function ComponentToTest() {
  const location = useLocation();
  console.log(location);
  const path = useResolvedPath('..');
  console.log(path);
  return <button onClick={() => navigate('..')}>navigate</div>;
}

I use the hook useResolvedPath to compute the navigation result and log it. In my application the relative path computed is correct but in my test it is always equals to '/' whatever the current location is.

Does someone has encounter and solved this problem?

EDIT

Ok, i understand what is the problem. The useResolvedPath is using the routingContext to compute the relative route so if we use '..' it pop to the previous route in the route tree.

With that, if i want to test my navigation i need to reproduce my route tree. Another solution is to use the real relative path by using the method resolvePath('..', location)

The resolvePath compute relative path from a path

resolvePath('..', '/user/project') ---> '/user'

the navigate function also use the RoutingContext so if i want to do a relative from the current path i have to do

const location = useLocation();
navigate(resolvePath('..', location.pathname));

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

再见回来2025-01-23 05:48:10

我遇到了这个问题,我解决的方法是编写整个应用程序路由层次结构,并仅挂载所需的组件。
例如:

<MemoryRouter
     initialEntries={['/1/page1/2/3']}>
     <Routes>
         <Route path="/:param1">
             <Route path="page1/*"
                  element={<MyComponent />}>
                  <Route path=":param2/*">
                      <Route path=":param3" />
                  </Route>
             </Route>
        </Route>
   </Routes>
</MemoryRouter>

I encountered this issue, the way I solved it was to write the whole app routing hierarchy, and mount the wanted component only.
for example:

<MemoryRouter
     initialEntries={['/1/page1/2/3']}>
     <Routes>
         <Route path="/:param1">
             <Route path="page1/*"
                  element={<MyComponent />}>
                  <Route path=":param2/*">
                      <Route path=":param3" />
                  </Route>
             </Route>
        </Route>
   </Routes>
</MemoryRouter>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文