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

React多步骤表单导航异常:Context未完成更新即跳转

问题

使用React、react-hook-form和react-query构建多步骤订单表单,初始包含客户信息、产品选择、订单总结三个可见步骤,根据所选产品会在产品选择与订单总结间动态显示1-5个额外步骤。采用React Context跟踪订单数据与可用步骤,完成每一步后调用后端API,后端返回完整订单对象用于更新OrderContext中的orderData,之后跳转至下一个合适步骤。

当前问题:跳转操作在OrderContext完全更新前执行,导致用户被导向订单总结页,而非产品选择后应新增的步骤。因后端会添加前端请求外的订单数据,无法使用乐观更新,必须依赖API返回对象。

解决方案

方案一:让goToNextStep基于最新订单数据计算下一步

当前goToNextStep依赖组件渲染时的currentStepIndex和visibleSteps,这两个值在orderData更新后不会立即更新。修改goToNextStep,允许传入最新的订单数据,直接基于该数据计算可见步骤和下一步:

  1. 修改OrderContext中的goToNextStep方法:
const goToNextStep = (targetOrderData?: IInternalApiDetailOrderResponseBody) => {
  const data = targetOrderData || orderData;
  if (!data) return;

  // 基于传入的最新数据计算可见步骤
  const updatedVisibleSteps = orderStepsData.filter(step => step.isVisible(data));
  // 获取当前步骤(保持原逻辑,优先从路径匹配)
  const currentStepInUpdated = findStepByPath(currentPath) || updatedVisibleSteps[0];
  const currentIndex = updatedVisibleSteps.findIndex(step => step.id === currentStepInUpdated.id);

  if (currentIndex < updatedVisibleSteps.length - 1) {
    const nextStep = updatedVisibleSteps[currentIndex + 1];
    navigate(`/orders/${orderId}/edit/${nextStep.path}`);
  }
};
  1. 在表单的onSuccess中调用goToNextStep时传入新的订单数据:
onSuccess(data) {
  const newOrderData = data.data.result;
  updateOrderData(newOrderData);
  goToNextStep(newOrderData); // 直接用新数据计算下一步
}

这种方式不需要等待组件重渲染,直接基于最新数据计算跳转目标,避免旧数据导致的错误跳转。

方案二:通过状态标记+useEffect等待组件更新后跳转

利用React的状态和副作用钩子,在orderData更新完成后再执行跳转:

  1. 在OrderContextProvider中添加状态并修改updateOrderData:
import { useState, useEffect } from 'react';

export const OrderContextProvider = ({ children }: { children: React.ReactNode }) => {
  // ... 其他现有代码
  const [shouldNavigateNext, setShouldNavigateNext] = useState(false);

  const updateOrderData = (updatedOrderData: IInternalApiDetailOrderResponseBody) => {
    queryClient.setQueryData(['order', orderId], updatedOrderData);
    setShouldNavigateNext(true); // 标记需要跳转
  };

  // 监听orderData和跳转标记,更新完成后执行跳转
  useEffect(() => {
    if (shouldNavigateNext && orderData) {
      goToNextStep();
      setShouldNavigateNext(false); // 重置标记
    }
  }, [shouldNavigateNext, orderData, goToNextStep]);

  // ... 其他现有代码
};
  1. 修改表单的onSuccess,只更新订单数据,不再手动调用跳转:
onSuccess(data) {
  updateOrderData(data.data.result);
}

这种方式利用React的渲染周期,确保visibleSteps和currentStepIndex都基于最新的orderData计算完成后,再执行跳转逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 13:14:55