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

React项目Material UI Stepper路由跳转与状态异常问题咨询

问题解决方案

问题1:需两次点击才能跳转的修复

问题原因

原有代码中所有<Link>的to属性都绑定了全局共享的url状态,第一次点击StepButton仅更新url状态,第二次点击Link才能使用更新后的路径跳转,同时嵌套的点击事件也存在冲突。

修复方案

移除全局的url状态,改用React Router的编程式导航,点击StepButton的同时完成状态更新和路由跳转,避免事件冲突。

  1. 首先导入路由导航方法:
import { useNavigate } from 'react-router-dom'
  1. 组件内声明导航实例并修改点击逻辑:
const navigate = useNavigate()
const handleStep = (step: number) => () => {
  setActiveStep(step);
  const targetUrl = getStepContent(step);
  navigate(targetUrl);
};
  1. 移除组件渲染中的<Link>嵌套,修改后的Step部分代码如下:
<Step key={label}>
  <StepButton onClick={handleStep(index)}>
    <StepLabel 
      classes={{ label: classes.label, active: classes.labelActive}}
      StepIconProps={{
        classes: { root: classes.icon, text: classes.iconText, active: classes.iconActive},
      }}>
      {label}
    </StepLabel>
  </StepButton>
</Step> 

问题2:页面加载后activeStep重置的修复

问题原因

组件的useState状态仅存在于组件生命周期中,路由跳转后Stepper组件重新挂载,状态会回到初始值。

修复方案

从当前路由路径反推对应的步骤索引,作为activeStep的初始值,同时监听路由变化同步更新状态。

  1. 导入路由路径监听方法:
import { useLocation } from 'react-router-dom'
  1. 新增路径匹配逻辑,同步步骤状态:
const location = useLocation();
// 匹配当前路由对应的步骤索引
const getCurrentStep = () => {
  const currentPath = location.pathname;
  for (let i = 0; i < 4; i++) {
    if (getStepContent(i) === currentPath) return i;
  }
  return 0;
}
// 初始化activeStep时直接匹配当前路由
const [activeStep, setActiveStep] = useState(getCurrentStep());

// 监听路由变化,同步更新activeStep
useEffect(() => {
  setActiveStep(getCurrentStep());
}, [location.pathname]);

完整修改后代码示例

import { useNavigate, useLocation } from 'react-router-dom';
import { useEffect, useState } from 'react';
// MUI相关导入保持原有逻辑不变

function getSteps() {
  return ['page1', 'page2', 'page3', 'page4'];
}

function getStepContent(step: number) {
  switch (step) {
    case 0:
      return "/page1"
    case 1:
      return "/page2"
    case 2:
      return "/page3"
    case 3:
      return "/page4"
    default:
      return "/page1"
  }
}

export default function HorizontalNonLinearStepper() {
  const classes = useStyles();
  const navigate = useNavigate();
  const location = useLocation();
  const steps = getSteps();

  // 匹配当前路由对应的步骤索引
  const getCurrentStep = () => {
    const currentPath = location.pathname;
    for (let i = 0; i < 4; i++) {
      if (getStepContent(i) === currentPath) return i;
    }
    return 0;
  }

  const [activeStep, setActiveStep] = useState(getCurrentStep());

  // 监听路由变化同步步骤状态
  useEffect(() => {
    setActiveStep(getCurrentStep());
  }, [location.pathname]);

  const handleStep = (step: number) => () => {
    setActiveStep(step);
    navigate(getStepContent(step));
  };
 
  return (
    <div className={classes.root}>
      <Stepper nonLinear activeStep={activeStep} className={classes.stepper}>
        {steps.map((label, index) =>  (
          <Step key={label}>
            <StepButton onClick={handleStep(index)}>
              <StepLabel 
                classes={{ label: classes.label, active: classes.labelActive}}
                StepIconProps={{
                  classes: { root: classes.icon, text: classes.iconText, active: classes.iconActive},
                }}>
                {label}
              </StepLabel>
            </StepButton>
          </Step> 
        ))}
      </Stepper>
    </div>
  );
}

内容的提问来源于stack exchange,提问作者park

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 21:54:03