如何在createBrowserRouter数据路由中使用useLocation Hook?
解决
useLocation() may be used only in the context of a <Router> component错误 问题原因
你在App组件里直接调用useLocation,但App是负责渲染<RouterProvider>的组件——此时还没进入React Router的上下文环境,自然无法使用useLocation这类依赖Router上下文的Hook。只有<RouterProvider>内部的子组件,才能访问到Router上下文。
解决方案:将useLocation逻辑移到Router上下文内部的组件中
把获取previousLocation的逻辑,放到路由内部的组件(比如根布局RootLayout)里,再处理模态路由的渲染。
步骤1:重构App组件,移除内部的useLocation
const App = () => { return ( <RouterProvider router={createBrowserRouter( createRoutesFromElements( <Route> <Route path="/" element={<RootLayout />} errorElement={<ErrorPage1 />} > <Route index element={<Landing />} /> <Route path="login" element={<Login />} /> </Route> <Route path="access" element={<AppLayout />} errorElement={<ErrorPage2 />} > <Route index element={<AppHome />} loader={usersLoader} action={newUserAction} /> <Route path="*" element={<NoMatchAppPage />} /> </Route> {/* 保留模态路由的配置 */} <Route path="start" element={<Modal />} /> </Route> ) )} /> ); }; export default App;
步骤2:在根布局组件中处理location逻辑
把之前App里的逻辑移到RootLayout,利用useLocation获取状态,同时处理模态框的显示与关闭:
import { useLocation, useNavigate, Outlet } from 'react-router-dom'; const RootLayout = () => { const location = useLocation(); const navigate = useNavigate(); const previousLocation = location.state?.previousLocation; // 关闭模态框时返回之前的页面 const closeModal = () => { navigate(previousLocation || '/'); }; return ( <div> {/* 渲染当前路由的内容 */} <Outlet /> {/* 当存在previousLocation时,渲染模态框 */} {previousLocation && <Modal onClose={closeModal} />} </div> ); };
步骤3:打开模态框时传递状态
在需要打开模态框的组件里,通过navigate传递previousLocation状态:
import { useLocation, useNavigate } from 'react-router-dom'; const SomeComponent = () => { const location = useLocation(); const navigate = useNavigate(); const openModal = () => { navigate('/start', { state: { previousLocation: location }, }); }; return <button onClick={openModal}>打开模态框</button>; };
核心逻辑说明
<RouterProvider>是React Router提供上下文的入口,只有它的子组件才能“感知”到Router的存在。App组件作为渲染<RouterProvider>的父级,不在这个上下文范围内,所以调用useLocation会报错。将逻辑移到路由内部组件后,就能正常访问Router上下文了。
内容的提问来源于stack exchange,提问作者Garfield Maytag
相关产品推荐
相关产品推荐

