当用<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 install
和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中通过。
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>
);
});