React-Router DOM分页功能异常问题排查与解决方案请求
问题解决:React Router 分页切换路径时顺序不匹配的问题
问题分析
你当前的实现存在核心问题:useState 的更新是异步的,但 <Link> 的跳转是同步触发的。点击按钮时,<Link> 会立即使用当前的路径值(更新前索引对应的路径)完成跳转,之后才会执行 setArrayIndex 更新状态。这就导致跳转的路径和预期的索引不同步,出现点击顺序和组件切换不匹配的问题。
另外,useRef 在这里完全多余——直接通过 array_index 计算路径即可,不需要额外维护 ref 变量。
解决方案:使用编程式导航(推荐)
改用 react-router-dom 提供的 useNavigate 钩子实现编程式导航,先计算出目标路径再直接跳转,完全规避异步更新的问题。
修正后的代码
import { useNavigate } from "react-router-dom"; import { useState } from "react"; import "./bottombar.css"; const Bottombar = () => { const pathArray = ["shop", "contact", "cart"]; const [arrayIndex, setArrayIndex] = useState(0); const navigate = useNavigate(); const handleNext = () => { // 先计算目标索引 const targetIndex = arrayIndex === pathArray.length - 1 ? 0 : arrayIndex + 1; setArrayIndex(targetIndex); // 直接跳转到目标路径 navigate(`/${pathArray[targetIndex]}`); }; const handlePrev = () => { // 先计算目标索引 const targetIndex = arrayIndex === 0 ? pathArray.length - 1 : arrayIndex - 1; setArrayIndex(targetIndex); // 直接跳转到目标路径 navigate(`/${pathArray[targetIndex]}`); }; return ( <div className="bottombar"> <div className="links"> <button onClick={handlePrev}>Previous</button> <button onClick={handleNext}>Next</button> </div> </div> ); }; export default Bottombar;
另一种方案:保留Link但同步计算路径
如果坚持使用 <Link>,可以在点击事件中直接计算目标路径,不依赖状态更新结果:
import { Link, useNavigate } from "react-router-dom"; import { useState } from "react"; import "./bottombar.css"; const Bottombar = () => { const pathArray = ["shop", "contact", "cart"]; const [arrayIndex, setArrayIndex] = useState(0); const navigate = useNavigate(); const handlePrev = (e) => { e.preventDefault(); const targetIndex = arrayIndex === 0 ? pathArray.length - 1 : arrayIndex - 1; setArrayIndex(targetIndex); navigate(`/${pathArray[targetIndex]}`); }; const handleNext = (e) => { e.preventDefault(); const targetIndex = arrayIndex === pathArray.length - 1 ? 0 : arrayIndex + 1; setArrayIndex(targetIndex); navigate(`/${pathArray[targetIndex]}`); }; return ( <div className="bottombar"> <div className="links"> <Link to="#" onClick={handlePrev}>Previous</Link> <Link to="#" onClick={handleNext}>Next</Link> </div> </div> ); }; export default Bottombar;
不过这种方式需要手动阻止 <Link> 的默认跳转行为,不如编程式导航直观,更推荐第一种方案。
关键优化点
- 移除多余的
useRef,直接通过索引计算路径 - 使用
useNavigate确保跳转路径和索引更新完全同步 - 用普通按钮或阻止默认行为的
<Link>避免同步跳转与异步状态更新的冲突
内容的提问来源于stack exchange,提问作者KABIR CHANDRIKAPURE
相关产品推荐
相关产品推荐

