React 测试库、动态导入和 React Router DOM 总是渲染未找到的组件
React testing library, dynamic import & React Router DOM always render the not-found component
我在测试简单导航时遇到了一些问题,
我有一个使用 react-router-dom 的 React 应用程序,App 组件被悬念包裹着。
我还动态导入我的组件以便能够代码拆分。
出于某种原因,在单元测试中,当我触发点击主页上的关于 link 的导航时。
它总是呈现 404 NotFound 组件,而不是存在的 about 组件
我做错了什么?
Main.js
const Main = () => <h1>Home page</h1>;
About.js
const About = () => <h1>About page</h1>;
NotFound.js
const NotFound = () => <div>404 this page does not exist</div>;
Nav.js
const Nav = () => (
<div className="dummy-nav">
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</div>
);
App.js
import React, { Component, Suspense, lazy } from "react";
import { Switch, Route } from "react-router-dom";
import Nav from "./Nav";
const Main = lazy(() => import(/* webpackChunkName: "Main" */ "./Main"));
const About = lazy(() => import(/* webpackChunkName: "About" */ "./About"));
const NotFound = lazy(() =>
import(/* webpackChunkName: "About" */ "./NotFound")
);
class App extends Component {
render() {
return (
<Suspense fallback={<div>Loading...</div>}>
<div>This is the App</div>
<Nav />
<Switch>
<Route exact path="/" component={Main} />
<Route path="/about" component={About} />
<Route render={() => <NotFound />} />
</Switch>
</Suspense>
);
}
}
app.test.js
function renderWithRouter(
ui,
{
route = "/",
history = createMemoryHistory({ initialEntries: [route] }),
...renderOptions
} = {}
) {
// eslint-disable-next-line react/prop-types
function Wrapper({ children }) {
return <Router history={history}>{children}</Router>;
}
return {
...render(ui, { wrapper: Wrapper, ...renderOptions }),
history
};
}
test("renders homepage by default and can navigate to about", async () => {
renderWithRouter(<App />);
screen.getByText(/Home page/i);
const link = screen.getByRole("link", { name: /About/i });
userEvent.click(link);
await waitFor(() => screen.getByText(/About page/i));
screen.debug();
});
这是一个代码沙箱,其中包含损坏的测试和我正在使用的应用程序结构,
如果您有任何使用和测试惰性和动态导入的技巧,请分享
https://codesandbox.io/s/react-router-suspense-lrnp7?file=/src/App.js
我终于找到了问题所在,但我不完全明白为什么。
问题是使用了最新版本的历史包 5.0.0.
损坏的示例 => https://codesandbox.io/s/history-v50-always-render-404-after-usereventclick-h8osi?file=/src/tests/test.js
降级到以前的版本 4.10.1 解决了这个问题。也就是说,任何点击 Link 都会导致呈现 404 页面或什么都不呈现。
History 4.10.1 的工作示例 => https://codesandbox.io/s/history-v4101-fix-404-madness-4uitj?file=/src/tests/react-router.js:413-451
查看最新历史版本的变化后,
我没有看到任何重大变化或任何明显的原因。
知道为什么会发生这种情况以及如何正确使用最新的历史记录吗?
如果您陷入这种 404 疯狂状态,请查看您的历史版本。
如果您想使用 history v5.x
,您应该使用 react-router-dom v6
。
我在测试简单导航时遇到了一些问题,
我有一个使用 react-router-dom 的 React 应用程序,App 组件被悬念包裹着。
我还动态导入我的组件以便能够代码拆分。
出于某种原因,在单元测试中,当我触发点击主页上的关于 link 的导航时。
它总是呈现 404 NotFound 组件,而不是存在的 about 组件
我做错了什么?
Main.js
const Main = () => <h1>Home page</h1>;
About.js
const About = () => <h1>About page</h1>;
NotFound.js
const NotFound = () => <div>404 this page does not exist</div>;
Nav.js
const Nav = () => (
<div className="dummy-nav">
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</div>
);
App.js
import React, { Component, Suspense, lazy } from "react";
import { Switch, Route } from "react-router-dom";
import Nav from "./Nav";
const Main = lazy(() => import(/* webpackChunkName: "Main" */ "./Main"));
const About = lazy(() => import(/* webpackChunkName: "About" */ "./About"));
const NotFound = lazy(() =>
import(/* webpackChunkName: "About" */ "./NotFound")
);
class App extends Component {
render() {
return (
<Suspense fallback={<div>Loading...</div>}>
<div>This is the App</div>
<Nav />
<Switch>
<Route exact path="/" component={Main} />
<Route path="/about" component={About} />
<Route render={() => <NotFound />} />
</Switch>
</Suspense>
);
}
}
app.test.js
function renderWithRouter(
ui,
{
route = "/",
history = createMemoryHistory({ initialEntries: [route] }),
...renderOptions
} = {}
) {
// eslint-disable-next-line react/prop-types
function Wrapper({ children }) {
return <Router history={history}>{children}</Router>;
}
return {
...render(ui, { wrapper: Wrapper, ...renderOptions }),
history
};
}
test("renders homepage by default and can navigate to about", async () => {
renderWithRouter(<App />);
screen.getByText(/Home page/i);
const link = screen.getByRole("link", { name: /About/i });
userEvent.click(link);
await waitFor(() => screen.getByText(/About page/i));
screen.debug();
});
这是一个代码沙箱,其中包含损坏的测试和我正在使用的应用程序结构, 如果您有任何使用和测试惰性和动态导入的技巧,请分享
https://codesandbox.io/s/react-router-suspense-lrnp7?file=/src/App.js
我终于找到了问题所在,但我不完全明白为什么。
问题是使用了最新版本的历史包 5.0.0.
损坏的示例 => https://codesandbox.io/s/history-v50-always-render-404-after-usereventclick-h8osi?file=/src/tests/test.js
降级到以前的版本 4.10.1 解决了这个问题。也就是说,任何点击 Link 都会导致呈现 404 页面或什么都不呈现。
History 4.10.1 的工作示例 => https://codesandbox.io/s/history-v4101-fix-404-madness-4uitj?file=/src/tests/react-router.js:413-451
查看最新历史版本的变化后,
我没有看到任何重大变化或任何明显的原因。
知道为什么会发生这种情况以及如何正确使用最新的历史记录吗?
如果您陷入这种 404 疯狂状态,请查看您的历史版本。
如果您想使用 history v5.x
,您应该使用 react-router-dom v6
。