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
相关产品推荐
相关产品推荐

