You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 10:33:13