Next.js使用redux-thunk dispatch后alert无法获取error最新状态问题
问题根因
- 你的thunk action(login函数)没有返回执行结果,且catch块捕获错误后没有向外抛出,所以
dispatch(login())返回的Promise永远是resolve状态,不会触发reject分支 - 你在then回调中直接读取的
error变量如果是通过useSelector从redux store获取的,回调执行时无法保证拿到最新的更新后状态,会出现读取到undefined的情况
可用解决方案
方案1:修改thunk返回操作状态,直接在dispatch回调中处理
首先修改loginAction.js的login函数,补全返回逻辑:
// loginAction.js 修改后 export const login = (email, password) => async (dispatch) => { try { dispatch({ type: USER_LOGIN_REQUEST }); const config = { headers: { "Content-Type": "application/json" } }; const { data } = await axios.post("/api/auth/login", { email, password }, config); dispatch({ type: USER_LOGIN_SUCCESS, payload: data }); localStorage.setItem("user", JSON.stringify(data.token)); // 成功时返回成功标识 return { success: true }; } catch (error) { const errMsg = error.response && error.response.data.message ? error.response.data.message : error.message; dispatch({ type: USER_LOGIN_FAIL, payload: errMsg }); // 失败时抛出错误,让Promise进入reject状态 throw new Error(errMsg); } }
再修改loginScreen.js的dispatch逻辑,区分成功和失败分支:
// loginScreen.js 修改后 dispatch(login(email, password)) .then(() => alert("success")) .catch((err) => alert(err.message));
方案2:监听redux状态变化触发提示(符合单向数据流规范)
如果不想改动thunk逻辑,可以通过useEffect监听store状态变化触发提示:
// loginScreen.js 新增逻辑 const { loading, error, userInfo } = useSelector(state => state.userLogin); useEffect(() => { // 登录请求结束后触发对应提示 if (!loading) { if (error) { alert(error); // 提示后清空错误状态,避免重复触发 dispatch({ type: USER_LOGIN_RESET }); } else if (userInfo) { alert("success"); } } }, [loading, error, userInfo, dispatch]); // 原有dispatch逻辑不需要加then回调,直接保留即可 dispatch(login(email, password));
需要在reducer中新增重置状态的case:
// loginReducer.js 新增case case USER_LOGIN_RESET: return {};
内容的提问来源于stack exchange,提问作者R4ve
相关产品推荐
相关产品推荐

