kid*_*kid 76 reactjs jestjs react-router react-router-dom react-hooks
请参阅下面的我的代码。我正在尝试添加此按钮,使用它返回上一页,react-router-dom
但出现以下错误,并且网站上的所有组件都消失了。
错误:
useNavigate() 只能在组件上下文中使用
我的代码:
function App() {
const navigate = useNavigate();
return (
<BrowserRouter>
<div>
<button onClick={() => navigate(-1)}>go back</button>
<Nav/>
<Routes>
<Route exact path="/" element={<Home/>}/>
<Route exact path="/home" element={<Home/>}/>
<Route exact path="/upcoming/:user" element={<Upcoming/>}/>
<Route exact path="/record/:user" element={<Record/>}/>
<Route path="*" element={<NotFound/>}/>
</Routes>
</div>
</BrowserRouter>
);
}
Run Code Online (Sandbox Code Playgroud)
这是我在控制台中收到的错误:
sli*_*wp2 107
此错误会在useNavigate中引发。useInRouterContext将检查组件(使用useNavigate
钩子)是否是<Router>
. 如果该组件不是该组件的后代<Router>
,则会抛出此错误。
下面的源代码解释了为什么不能在组件之外使用useNavigate
, :useLocation
Router
useNavigate
在底层使用useLocation
时,将从LocationContext提供程序useLocation
获取位置。如果您想获取反应上下文,则应该将该组件呈现为上下文提供者的后代。 组件使用LocationContext.Provider和NavigationContext.Provider。这就是为什么您需要将组件渲染为孩子,以便钩子可以从提供者获取上下文数据。Router
useNavigate
NavigationContext
LocationContext
您的环境是浏览器,因此您需要使用BrowserRouter
. BrowserRouter
是基于Router
.
重构为:
App.jsx
:
function App() {
const navigate = useNavigate();
return (
<div>
<button onClick={() => navigate(-1)}>go back</button>
<Nav/>
<Routes>
<Route exact path="/" element={<Home/>}/>
<Route exact path="/home" element={<Home/>}/>
<Route exact path="/upcoming/:user" element={<Upcoming/>}/>
<Route exact path="/record/:user" element={<Record/>}/>
<Route path="*" element={<NotFound/>}/>
</Routes>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
index.jsx
:
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
ReactDOM.render(
<BrowserRouter>
<App/>
</BrowserRouter>,
document.getElementById('root')
)
Run Code Online (Sandbox Code Playgroud)
小智 27
我也遇到了同样的问题,但是测试了一个带有钩子的组件useNavigate
。通过将我的组件包装在Route
withRoutes
和中解决了这个问题BrowserRouter
。希望这可以帮助其他有同样错误的人。
let container = null;
beforeEach(() => {
container = document.createElement("div");
document.body.appendChild(container);
});
afterEach(() => {
// cleanup on exiting
unmountComponentAtNode(container);
container.remove();
container = null;
});
test('finds qualified insurrance policies', () => {
act(() => {
render(
<BrowserRouter>
<Routes>
<Route path="*" element= {<QuaifiedPolicies policyTypes={false} />}/>
</Routes>
</BrowserRouter>
, container);
});
expect(screen.getByLabelText('some text'))
});
Run Code Online (Sandbox Code Playgroud)
bre*_*nse 23
供将来参考:也可能会出现此错误
<Router>
自react-router-dom
并导入useNavigate
自react-router
useNavigate
从不同版本的软件包导入等BrowserRouter
,例如 v5 和 v6Rah*_*rma 16
您正在使用外部BrowserRouter
提供商的钩子。这就是你收到错误的原因。像下面这样重构你的组件来解决这个问题:
function Root() {
const navigate = useNavigate();
return (
<div>
<button onClick={() => navigate(-1)}>go back</button>
<Nav />
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="/home" element={<Home />} />
<Route exact path="/upcoming/:user" element={<Upcoming />} />
<Route exact path="/record/:user" element={<Record />} />
<Route path="*" element={<NotFound />} />
</Routes>
</div>
);
}
function App() {
return (
<BrowserRouter>
<Root />
</BrowserRouter>
);
}
Run Code Online (Sandbox Code Playgroud)