Redux Thunk如何等待第一个dispatch返回数据后执行第二个dispatch
问题根源
- 调用
then报错的核心原因是你定义的thunkA没有返回Promise:Redux Thunk 只有在 thunk 函数返回 Promise 时,dispatch(thunk函数)才会返回对应的Promise实例,才可以链式调用.then()。你当前的thunkA仅执行了dispatch(getOauthKey()),没有返回值,所以dispatch(thunkA())的结果是undefined,调用then自然会抛出类型错误。 - 另外即使修复了Promise返回问题,你在
then中直接取当前作用域的oAuthKey.access_token也会拿不到最新值:useEffect的回调是初始化时生成的闭包,里面存储的oAuthKey是组件首次渲染的初始值,等第一个请求完成更新Store后,闭包里的oAuthKey还是旧的初始值,传给第二个接口的参数会出错。
最优修复方案
不需要拆分多个thunk或者监听Store变量,直接写一个组合thunk就能实现两次请求的顺序执行:
- 首先确保你的
getOauthKeythunk本身返回Promise,且将获取到的token作为返回值传出:
// getOauthKey的标准实现示例 const getOauthKey = () => async (dispatch) => { // 发起Twitch鉴权请求 const authRes = await fetch('你的Twitch鉴权接口地址', { method: 'POST', // 补充你的鉴权请求配置 }) const oauthData = await authRes.json() // 将密钥存入Store dispatch({ type: 'SAVE_OAUTH_KEY', payload: oauthData }) // 必须返回token,方便后续链式调用获取 return oauthData.access_token }
- 编写组合thunk,按顺序执行两次请求:
const fetchTwitchStreamData = () => async (dispatch) => { // 第一步:获取鉴权密钥 const accessToken = await dispatch(getOauthKey()) // 第二步:用密钥请求流数据 await dispatch(getAllStreams(accessToken)) }
- 组件内直接调用该组合thunk即可,不需要额外的refresh变量和监听useEffect:
useEffect(() => { dispatch(fetchTwitchStreamData()) }, [dispatch])
如果你坚持用原链式写法的修复方案
如果不想改原有拆分thunk的结构,需要做两处修改:
- 给
thunkA加上返回值,返回getOauthKey的Promise - 在
then中通过getState获取Store中最新的密钥,不要用闭包中的旧值
const thunkA = () => (dispatch, getState) => { // 新增return返回Promise return dispatch(getOauthKey()) } const thunkB = (key) =>(dispatch, getState) => { dispatch(getAllStreams(key)) } useEffect(()=> { dispatch(thunkA()).then(() => { // 从getState获取最新的Store数据,替换闭包中的旧oAuthKey const latestAccessToken = getState().你的oAuthKey对应Store模块名.access_token dispatch(thunkB(latestAccessToken)) }); }, [dispatch])
内容的提问来源于stack exchange,提问作者Misen
相关产品推荐
相关产品推荐

