为什么在 react 中调用的 action 函数被包裹在 dispatch 中?

Why are action function called wrapped inside dispatch in react?

我刚刚在网上浏览了一些 react-redux 代码,基本上我遇到了下面的一组代码,它基本上是一个充满 ACTIONS 的 js 文件,只是为了提供一些 redux 组合的上下文此处使用 redux-thunk:

export const init = () => async dispatch => {
  dispatch({ type: TYPES.SET_LOADING });
  await dispatch(getConfig());
  await dispatch(getGenres());
  dispatch({ type: TYPES.REMOVE_LOADING });
};

// Action Creator to get the config object from the API
export const getConfig = () => async dispatch => {
  const res = await tmdbAPI.get('/configuration');
  dispatch({
    type: TYPES.GET_CONFIG,
    payload: res.data,
  });
};

我有点困惑为什么 getConfig 函数被包裹在 dispatch 中?

Redux thunk 只是可以执行副作用的 redux 操作。所以

export const init = () => async dispatch => {
  dispatch({ type: TYPES.SET_LOADING });
  await dispatch(getConfig());
  await dispatch(getGenres());
  dispatch({ type: TYPES.REMOVE_LOADING });
};

只是一个异步初始化函数,调用时以同步方式执行步骤。

关键是 thunk 可以分派其他 thunks/actions/etc 所以 init thunk 只是分派本身是异步的 getConfig() 操作,所以 init 函数的下一步直到配置 API 调用完成(可能是因为其他一些代码依赖于它)

如果你不想,请不要包装 像这样

export const init = () => async dispatch => {
  dispatch({ type: TYPES.SET_LOADING });
  dispatch(await getConfig());
  dispatch({ type: TYPES.REMOVE_LOADING });
};

//this is not using redux-thunk

// Action Creator to get the config object from the API
export const getConfig = async () => {
  const res = await tmdbAPI.get('/configuration');
  return {
    type: TYPES.GET_CONFIG,
    payload: res.data,
  };
};

重要
但是有很多原因为什么要用 dispatch 包装动作。

举一个例子。

当你想一步一步获取多个数据时

export const getData = () => async dispatch => {
  dispatch({
    type: DATA_LOADING_START
  });
  try {
    const res = await tmdbAPI.get('/url1');
    dispatch({
      type: DATA1_LOADED,
      payload: res.data,
    });
    const res = await tmdbAPI.get('/url2');
    dispatch({
      type: DATA2_LOADED,
      payload: res.data,
    });
  } catch (err) {
    // handle error
  }
  dispatch({
    type: DATA_LOADING_END
  });
};
//this is using redux-thunk

@AlexanderSolonik
问题: 为什么要通过调度包装动作?

因为dispatch()将动作结果发送给reducer。