在 v6 React 路由器中测试页面时"Cannot read properties of undefined (reading 'pathname')"



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

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

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

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属性:

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

目前还不清楚v6的等价物是什么;我试着切换到navigator={history},但还是出现了同样的错误。

要进行复制,请将以下文件复制到一个新目录中,然后运行npm installnpm 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中通过。

React Router v6将历史划分为多个部分,对于此用例,相关部分是导航器位置。这一变化在使用useNavigate而不是useHistory中有所暗示,您可以在Router道具中使用的Navigator类型的定义中看到:

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

仅仅将history={history}更改为navigator={history},仍然没有定义路由器试图访问pathname(以及其他属性(的location属性。要使测试再次工作,请按如下方式更新渲染:

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>
);
});

注意React Router 6.4中的history不再作为依赖项包含,因此如果您没有明确安装它,则需要将其添加回。

为了防止有人在尝试了这里发布的所有解决方案后陷入困境,无法弄清楚发生了什么,请确保您导入了正确的Router:

如果您有:import { Router } from "react-router-dom";

更改导入:import { BrowserRouter as Router } from "react-router-dom";

这是我对这个问题的解决方案,来自我在Udemy上学习的一门课程:

const { render } = require("@testing-library/react");
const { createBrowserHistory } = require("history");
const React = require("react");
const { unstable_HistoryRouter: HistoryRouter } = require("react-router-dom");
it("works", () => {
const history = createBrowserHistory();
render(
<HistoryRouter history={history}></HistoryRouter>
);
});

相关内容

最新更新