Formik提交时无法传递Node.js后端错误,仍跳转至登录页
解决Formik onSubmit中无法正确处理后端返回错误及页面跳转问题
问题根源
当前代码中dispatch(registerUser(values))是异步操作,但在onSubmit里直接同步判断!error——此时Redux状态还未更新,错误状态判断完全无效,导致不管后端是否返回错误,都会执行页面跳转。同时Redux状态更新是异步的,无法在onSubmit中直接获取最新的error值。
解决方案1:将onSubmit改为异步函数,等待Thunk执行结果
假设你的registerUser是Redux Toolkit的createAsyncThunk生成的Thunk(默认返回Promise),可以用async/await等待操作完成,仅在成功时跳转:
const onSubmit = async (values) => { if (values.password === values.passConfirm) { if (values.cPartner || values.aPartner || values.sPartner) { setCheckboxError(false); try { // unwrap()会获取Thunk的成功值,若失败则抛出错误 await dispatch(registerUser(values)).unwrap(); navigate("/login"); // 仅注册成功时跳转 } catch (err) { console.error("注册失败:", err.message); // 可选:用Formik的setErrors将后端错误同步到表单错误体系 // setErrors({ apiError: err.message }); } } else { setCheckboxError(true); } } else { console.log("mot de passe non conforme!!"); } };
解决方案2:用useEffect监听Redux状态变化处理跳转
如果不想修改onSubmit为异步,可以监听Redux中的注册成功/错误状态,在状态变更时处理跳转:
1. 先确保Redux Slice包含成功状态
// authentificationSlice.js import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; export const registerUser = createAsyncThunk( 'auth/registerUser', async (userData) => { const response = await fetch('/api/register', { method: 'POST', body: JSON.stringify(userData), headers: { 'Content-Type': 'application/json' } }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message); } return response.json(); } ); const authentificationSlice = createSlice({ name: 'authentification', initialState: { error: null, isSuccess: false, // 新增成功状态 }, reducers: { resetAuthState: (state) => { state.isSuccess = false; state.error = null; } }, extraReducers: (builder) => { builder .addCase(registerUser.fulfilled, (state) => { state.isSuccess = true; state.error = null; }) .addCase(registerUser.rejected, (state, action) => { state.error = action.error; state.isSuccess = false; }); } }); export const { resetAuthState } = authentificationSlice.actions; export default authentificationSlice.reducer;
2. 在组件中添加useEffect监听状态
const FormIscriptionEtape1 = () => { const [checkboxError, setCheckboxError] = useState(false); const [showPassword, setShowPassword] = useState(false); const { error, isSuccess } = useSelector((store) => store.authentification); const dispatch = useDispatch(); const navigate = useNavigate(); // 监听注册成功状态,跳转后重置状态避免重复触发 useEffect(() => { if (isSuccess) { navigate("/login"); dispatch(resetAuthState()); } }, [isSuccess, navigate, dispatch]); const onSubmit = (values) => { if (values.password === values.passConfirm) { if (values.cPartner || values.aPartner || values.sPartner) { setCheckboxError(false); dispatch(registerUser(values)); } else { setCheckboxError(true); } } else { console.log("mot de passe non conforme!!"); } }; // 其他组件代码... };
额外优化:将后端错误同步到Formik错误体系
如果需要把后端错误和Formik的表单错误统一展示,可以在捕获错误时调用Formik的setErrors:
// 在Formik初始化时解构setErrors const { setErrors, /* 其他属性 */ } = useFormik({ /* ... */ }); // 在方案1的catch块中: catch (err) { setErrors({ apiError: err.message }); }
然后在组件中添加错误展示:
{errors.apiError && <p className="validation_problems">{errors.apiError}</p>}
内容的提问来源于stack exchange,提问作者Abderrazak Wassim
相关产品推荐
相关产品推荐

