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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 11:31:01