React中点击按钮时如何等待异步Redux Action Dispatch执行完成?
React Redux登录请求:等待dispatch完成后执行后续代码
问题核心
你遇到的问题是:调用userLogin dispatch后,后续判断isLoggedIn的代码会立刻执行——因为Redux thunk的异步action没有返回Promise,导致await无效;同时组件中的isLoggedIn是当前props的快照,dispatch后状态还未更新,直接判断拿到的是旧值。
解决方案
1. 让Action Creator返回Promise
修改authActions.js中的userLogin,使用async/await让thunk返回异步操作的Promise:
export const userLogin = (userCredentials) => { // 改成async函数,thunk会自动返回这个函数的Promise return async (dispatch) => { try { dispatch(sendLoginRequest()); // 用await等待axios请求完成 const response = await axios.post('http://localhost:3001/auth/login', userCredentials); console.log(response.status); dispatch(loginSucccess()); } catch(err) { console.log("incorrect credentials"); dispatch(loginFailure('incorrect credentials')); } }; };
2. 在组件中正确等待并处理状态变化
首先,把loading和error也映射到组件props中:
const mapStateToProps = (state) => { return { isLoggedIn: state.auth.isLoggedIn, loading: state.auth.loading, error: state.auth.error } }
然后修改handleLogin为async函数,并通过useEffect监听状态变化处理后续逻辑(不能直接在dispatch后判断isLoggedIn,此时状态还未更新):
import React, { useState, useEffect } from 'react'; // ...其他导入 function Login({ isLoggedIn, loading, error, userLogin }) { // ...原有state定义 const handleLogin = async () => { const userCredentials = { email: email, password: password } // 现在可以await userLogin,等待异步请求完成 await userLogin(userCredentials); } // 监听isLoggedIn和loading的变化,处理登录结果 useEffect(() => { if (isLoggedIn) { console.log('登录成功'); // 这里可以做页面跳转、用户信息初始化等操作 } else if (!loading && error) { console.log('登录失败:', error); } }, [isLoggedIn, loading, error]); // ...原有JSX返回 }
为什么原来的方法无效?
- 你之前的
userLogin返回的thunk函数没有返回异步操作的Promise,所以await只是等待thunk函数本身执行完毕,而非里面的axios请求。改成async函数后,thunk会自动传递这个Promise,才能正确等待异步请求完成。 - 组件中的
isLoggedIn是props,只有当Redux状态更新并触发组件重新渲染后,props才会更新。所以dispatch后立刻判断拿到的是更新前的旧值,必须通过useEffect监听状态变化来处理后续逻辑。
内容的提问来源于stack exchange,提问作者kartikey rana
相关产品推荐
相关产品推荐

