如何使用React Router Dom同步组件路由与状态?
浏览器激活路由与组件状态同步方案
问题场景
点击导航栏"Route 2"时,该元素会因激活路由高亮,浏览器路由显示/route2;但刷新浏览器后,导航栏会高亮Navbar组件初始状态的"Route 1",而浏览器路由仍保持/route2,需要同步二者状态。
解决方案一:使用NavLink替代自定义状态
react-router-dom提供的NavLink组件自带路由激活判断能力,无需手动维护selected状态,是最简洁的解决方案:
修改后的Navbar组件:
import { NavLink } from "react-router-dom"; const Navbar = () => { return ( <div className="flex justify-between items-center sticky top-0 border-b bg-background px-4 h-12 z-10"> <h1>App Name</h1> <div className="flex gap-4 h-8 items-center"> <NavLink to="/route1" className={({ isActive }) => cn( "hover:underline hover:text-blue-500", isActive ? "text-blue-500" : null )} > <h2>Route 1</h2> </NavLink> <NavLink to="/route2" className={({ isActive }) => cn( "hover:underline hover:text-blue-500", isActive ? "text-blue-500" : null )} > <h2>Route 2</h2> </NavLink> </div> </div> ); };
说明:
NavLink会自动根据当前路由判断isActive状态- 通过
className接收的回调函数,可根据isActive动态设置样式 - 移除了手动维护的
selected状态和点击事件,简化代码逻辑
解决方案二:通过useLocation同步路由与组件状态
如果需要保留自定义状态逻辑,可使用useLocation监听路由变化,同步更新组件状态:
修改后的Navbar组件:
import { useLocation } from "react-router-dom"; const Navbar = () => { const location = useLocation(); // 根据当前路由初始化selected状态 const [selected, setSelected] = React.useState(() => { return location.pathname === "/route2" ? 1 : 0; }); // 监听路由变化,更新selected状态 React.useEffect(() => { setSelected(location.pathname === "/route2" ? 1 : 0); }, [location.pathname]); return ( <div className="flex justify-between items-center sticky top-0 border-b bg-background px-4 h-12 z-10"> <h1>App Name</h1> <div className="flex gap-4 h-8 items-center"> <Link to="/route1" onClick={() => setSelected(0)}> <h2 className={cn( "hover:underline hover:text-blue-500", selected === 0 ? "text-blue-500" : null )} > Route 1 </h2> </Link> <Link to="/route2" onClick={() => setSelected(1)}> <h2 className={cn( "hover:underline hover:text-blue-500", selected === 1 ? "text-blue-500" : null )} > Route 2 </h2> </Link> </div> </div> ); };
说明:
- 使用
useLocation获取当前路由信息 - 初始化状态时根据当前路由设置
selected,解决刷新后状态不一致问题 - 通过
useEffect监听location.pathname变化,实时同步状态
额外提示
原代码中Link to="route2"建议改为to="/route2",避免相对路径导致的路由跳转异常。
内容的提问来源于stack exchange,提问作者Simon1
相关产品推荐
相关产品推荐

