“无法读取未定义的属性(读取‘路径名’)";在 v6 React Router 中测试页面时 [英] "Cannot read properties of undefined (reading 'pathname')" when testing pages in the v6 React Router

查看:16
本文介绍了“无法读取未定义的属性(读取‘路径名’)";在 v6 React Router 中测试页面时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 测试组件时,例如在我对 推荐的路由方法的回答中在 react-router 的路由中进行基于测试,我经常使用以下模式来访问当前 location 以进行测试:

When testing components with <Link>s, for example in my answer to Recommended approach for route-based tests within routes of react-router, I often use the following pattern to get access to the current location for testing purposes:

const renderInRouter = () => {
  const history = createMemoryHistory();
  const wrapper = render(
    <Router history={history}>
      <MyPage />
    </Router>
  );
  return { ...wrapper, history };
}

这在 v5.3 之前运行良好,但在升级到 v6 后我得到:

This worked fine up to v5.3, but after upgrading to v6 I get:

 FAIL  ./demo.test.js
  ✕ works (205 ms)

  ● works

    TypeError: Cannot read properties of undefined (reading 'pathname')

      at Router (../packages/react-router/index.tsx:281:5)

      ...

迁移文档,到目前为止,v6 还没有测试指南,尽管 API参考确实表明不再需要 history 道具:

This use-case isn't covered in the migration docs, v6 has no testing guides so far and, although the API reference does show that the history prop is no longer expected:

interface RouterProps {
  basename?: string;
  children?: React.ReactNode;
  location: Partial<Location> | string;
  navigationType?: NavigationType;
  navigator: Navigator;
  static?: boolean;
}

不清楚 v6 的等价物是什么;我尝试切换到 navigator={history} 但仍然遇到相同的错误.

it's not clear what the v6 equivalent is; I tried switching to navigator={history} but still got the same error.

要复制,请将以下文件复制到新目录中并运行 npm install 然后 npm test:

To reproduce, copy the following files into a new directory and run npm install then npm test:

package.json

{
  "name": "router6-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "jest"
  },
  "jest": {
    "testEnvironment": "jsdom"
  },
  "babel": {
    "presets": [
      "@babel/preset-react"
    ]
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/preset-react": "^7.16.0",
    "@testing-library/react": "^12.1.2",
    "jest": "^27.3.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^6.0.0"
  }
}

index.test.js:

const { render } = require("@testing-library/react");
const { createMemoryHistory } = require("history");
const React = require("react");
const { Router } = require("react-router-dom");

it("used to work", () => {
  render(
    <Router history={createMemoryHistory()}></Router>
  );
});

如果你npm install --save-dev react-router@5并再次运行npm test,你可以看到这在v5中通过了.

If you npm install --save-dev react-router@5 and run npm test again, you can see that this passes in v5.

推荐答案

React Router v6 将历史拆分成多个部分,对于这个用例,相关部分是 navigator位置.使用useNavigate 而不是 useHistory,你可以在 Navigator 类型的定义中看到 >路由器道具:

React Router v6 splits apart the history into multiple pieces, for this use case the relevant parts are the navigator and the location. This change is hinted at in Use useNavigate instead of useHistory, and you can see it in the definition of the Navigator type used in the Router props:

export declare type Navigator = Omit<History, "action" | "location" | "back" | "forward" | "listen" | "block">;

只是将 history={history} 更改为 navigator={history} 仍然留下了 location 道具,路由器试图从中访问 pathname (其他属性),未定义.要让测试再次工作,请按如下方式更新渲染:

Just changing history={history} to navigator={history} still left the location prop, from which the router was trying to access the pathname (among other properties), undefined. To get the test working again, update the rendering as follows:

const { render } = require("@testing-library/react");
const { createMemoryHistory } = require("history");
const React = require("react");
const { Router } = require("react-router-dom");

it("works", () => {
  const history = createMemoryHistory();
  render(
    <Router location={history.location} navigator={history}></Router>
  );
});

这篇关于“无法读取未定义的属性(读取‘路径名’)";在 v6 React Router 中测试页面时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆