我为基本导航添加了React Router,并且工作正常,但是当我运行测试时,它会返回错误。
Error: Uncaught [Error: Invariant failed: You should not use Switch outside a Router]
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
import { BrowserRouter } from "react-router-dom";
import * as serviceWorker from "./serviceWorker";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root")
);
serviceWorker.unregister();
app.js
import React from "react";
import { Normalize } from "styled-normalize";
import { Switch, Route } from "react-router-dom";
import Home from "./pages/Home";
import FooterBarNavigator from "./navigators/FooterBarNavigator";
import Favorites from "./pages/Favorites";
import Finder from "./pages/Finder";
import Notifications from "./pages/Notifications";
import Profile from "./pages/Profile";
function App() {
return (
<div className="App">
<Normalize />
<FooterBarNavigator />
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/favorites" component={Favorites} />
<Route exact path="/finder" component={Finder} />
<Route exact path="/notifications" component={Notifications} />
<Route exact path="/profile" component={Profile} />
</Switch>
</div>
);
}
export default App;
FooterBarNavigator.js
import React from "react";
import styled from "styled-components";
import homeIcon from "../../assets/icons/home.svg";
import favoritesIcon from "../../assets/icons/favorite.svg";
import serachIcon from "../../assets/icons/search.svg";
import notificationsIcon from "../../assets/icons/notifications.svg";
import profileIcon from "../../assets/icons/profile.svg";
import { Link } from "react-router-dom";
const FooterBarNavigator = () => {
return (
<StyledFooterBarNavigator>
<Link to="/">
<StyledSectionIcon src={homeIcon} alt="" />
</Link>
<Link to="/favorites">
<StyledSectionIcon src={favoritesIcon} alt="" />
</Link>
<Link to="/finder">
<StyledSectionIcon src={serachIcon} alt="" />
</Link>
<Link to="/notifications">
<StyledSectionIcon src={notificationsIcon} alt="" />
</Link>
<Link to="/profile">
<StyledSectionIcon src={profileIcon} alt="" />
</Link>
</StyledFooterBarNavigator>
);
};
const StyledFooterBarNavigator = styled.div`
display: grid;
position: fixed;
width: 100%;
bottom: 0;
grid-gap: 1rem;
grid-template-columns: repeat(5, auto);
grid-template-rows: auto;
align-items: center;
`;
const StyledSectionIcon = styled.img`
height: 35px;
padding: 10px;
margin: auto auto 5px auto;
display: block;
`;
export default FooterBarNavigator;
app.test.js
import React from 'react';
import { render } from '@testing-library/react';
import App from '../../components/App';
test('renders learn react link', () => {
const { getByText } = render(<App />);
const linkElement = getByText(/home/i);
expect(linkElement).toBeInTheDocument();
});
package.json
{
"name": "app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-lazyload": "^2.6.8",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
"styled-components": "^5.1.1",
"styled-normalize": "^8.0.7"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
答案 0 :(得分:1)
在index.js中,您可以通过将<App />
组件与<BrowserRouter />
一起包含来正确包装路由,但是您尚未在测试中完成此操作,因此只需更改:
const { getByText } = render(<App />);
收件人:
const { getByText } = render(
<BrowserRouter>
<App />
</BrowserRouter>
);
完整的新测试文件:
import React from 'react';
import { render } from '@testing-library/react';
import { BrowserRouter } from "react-router-dom";
import App from '../../components/App';
test('renders learn react link', () => {
const { getByText } = render(
<BrowserRouter>
<App />
</BrowserRouter>
);
const linkElement = getByText(/home/i);
expect(linkElement).toBeInTheDocument();
});