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

ShippingScreen表单提交异常:点击无响应且循环重定向修复请求

问题

点击表单提交按钮后无法正常完成导航:在ShippingScreen页面填写信息并提交后,页面会重定向回ShippingScreen并进入持续循环,仅能通过刷新页面终止该行为。期望实现表单提交后无需刷新页面,直接导航至PaymentScreen页面。

相关代码

组件逻辑代码

useEffect(() => {
  if (!userInfo) {
    navigate("/signin?redirect=/shipping");
  }
},[userInfo,navigate]);

const submitHandler = (e) => {
  e.preventDefault();
  ctxDispach({
    type: "SAVE_SHIPPING_ADDRESS",
    payload: {
      firstName,
      lastName,
      address,
      city,
      states,
      postalCode,
      country,
      location: shippingAddress.location,
    },
  });
  localStorage.setItem(
    "shippingAddress",
    JSON.stringify({
      firstName,
      lastName,
      address,
      city,
      states,
      postalCode,
      country,
    })
  );
  navigate("/payment");
};

useEffect(() => {
  ctxDispach({ type: "SET_FULLBOX_OFF" });
}, [ctxDispach, fullBox]);

表单渲染代码

return (
  <div>
    <Helmet>
      <title>Shipping Address</title>
    </Helmet>
    <CheckoutSteps step1 step2></CheckoutSteps>
    <div className="container small-container">
      <h1 className="my-3"> Shipping Address</h1>
      <Form onSubmit={submitHandler}>
        <Form.Group>
          <Form.Label> First Name </Form.Label>
          <Form.Control
            value={firstName}
            onChange={(e) => setFirstName(e.target.value)}
            required
          ></Form.Control>
        </Form.Group>
        <Form.Group>
          <Form.Label>Last Name</Form.Label>
          <Form.Control
            value={lastName}
            onChange={(e) => setLastName(e.target.value)}
            required
          ></Form.Control>
        </Form.Group>
        <Form.Group>
          <Form.Label>Address</Form.Label>
          <Form.Control
            value={address}
            onChange={(e) => setAddress(e.target.value)}
            required
          ></Form.Control>
        </Form.Group>
        <Form.Group>
          <Form.Label> City </Form.Label>
          <Form.Control
            value={city}
            onChange={(e) => setCity(e.target.value)}
            required
          ></Form.Control>
        </Form.Group>
        <Form.Group>
          <Form.Label>State</Form.Label>
          <Form.Control
            value={states}
            onChange={(e) => setStates(e.target.value)}
          ></Form.Control>
        </Form.Group>
        <Form.Group>
          <Form.Label> Postal </Form.Label>
          <Form.Control
            value={postalCode}
            onChange={(e) => setPostalCode(e.target.value)}
            required
          ></Form.Control>
        </Form.Group>
        <Form.Group>
          <Form.Label> Country </Form.Label>
          <Form.Control
            value={country}
            onChange={(e) => setCountry(e.target.value)}
            required
          ></Form.Control>
        </Form.Group>
        <div className="mb-3">
          <Button
            id="chooseOnMap"
            type="button"
            variant="light"
            onClick={() => navigate("/map")}
          >
            Choose Location On Map
          </Button>
          {shippingAddress.location && shippingAddress.location.lat ? (
            <div>
              Lattitude: {shippingAddress.location.lat}
              Longitude: {shippingAddress.location.lng}
            </div>
          ) : (
            <div>No Location</div>
          )}
        </div>
        <div className="mb-3">
          <Button variant="primary" className="cusButton" type="submit">
            Continue
          </Button>
        </div>
      </Form>
    </div>
  </div>
);
}

修复方案

1. 修复无限循环的useEffect

第二个useEffect依赖了fullBox,但内部执行的SET_FULLBOX_OFF动作会触发fullBox状态变化,进而再次触发该useEffect,形成状态循环干扰组件渲染和导航。修改依赖项,确保仅在组件挂载时执行一次:

useEffect(() => {
  ctxDispach({ type: "SET_FULLBOX_OFF" });
}, [ctxDispach]); // 移除fullBox依赖,避免循环触发

2. 确保userInfo状态稳定

第一个useEffect会在userInfo变化时触发跳转,如果提交表单时userInfo意外变为null/undefined,会触发登录页重定向后回到ShippingScreen,形成循环。检查SAVE_SHIPPING_ADDRESS对应的reducer逻辑,确保它不会修改userInfo:

// 示例reducer逻辑
case "SAVE_SHIPPING_ADDRESS":
  return {
    ...state,
    shippingAddress: payload,
    // 不要添加修改userInfo的代码
  };

3. 验证PaymentScreen的路由守卫逻辑

如果PaymentScreen存在路由守卫,要求必须存在已保存的配送地址,而提交后地址保存存在延迟,会导致PaymentScreen判断地址未保存并跳转回ShippingScreen。可做以下调整:

  • 在ShippingScreen的submitHandler中,确保配送地址已成功保存到store后再执行导航(若使用异步状态更新,可通过useSelector监听状态变化后触发导航);
  • 在PaymentScreen中增加加载状态,避免立即跳转:
// PaymentScreen示例逻辑
const shippingAddress = useSelector(state => state.cart.shippingAddress);
const navigate = useNavigate();

useEffect(() => {
  if (!shippingAddress) {
    // 增加延迟判断,避免频繁跳转
    const timer = setTimeout(() => {
      navigate("/shipping");
    }, 100);
    return () => clearTimeout(timer);
  }
}, [shippingAddress, navigate]);

4. 优化导航触发时机

如果使用Redux异步中间件(如Thunk)处理状态更新,需确保SAVE_SHIPPING_ADDRESS动作完成后再执行导航;若为同步动作,可保持现有逻辑,但需确认状态更新同步完成。

内容的提问来源于stack exchange,提问作者Cyan the Computer Scientist

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 02:55:14