【问题标题】:Calling one redux action from one store slice in another store slice从另一个存储切片中的一个存储切片调用一个 redux 操作
【发布时间】:2021-08-05 14:20:12
【问题描述】:

我是 redux 的新手。在我的应用程序中,我正在使用一些带有 redux thunk 的异步操作。 例如,我有这个从 API 加载电影的操作:

export const loadMovies = (url) => async (dispatch) => {
  const response = await fetch(url);
  const result = await response.json();
  const { total_pages: totalPages, results: movies } = result;
  dispatch(moviesLoaded(totalPages, movies));
};

如果没有电影要加载怎么办(在数据库中搜索没有给我结果),所以我想将状态(它是另一个 redux 存储切片)更新为“没有电影”。并根据该状态呈现不同的组件。

所以我的新动作是这样的:

    export const loadMovies = (url) => async (dispatch) => {
      const response = await fetch(url);
      const result = await response.json();
      if (result) {
      const { total_pages: totalPages, results: movies } = result;
      dispatch(moviesLoaded(totalPages, movies));
      } else {
       dispatch(updateStatus('no-movies')) // updateStatus is imported from another redux store slice
      }
    };

我想知道这样做是否可以。或者,将操作从一个存储切片导入另一个存储切片是一种不好的做法。还有什么是处理这种情况的更好方法。

【问题讨论】:

    标签: javascript reactjs redux redux-thunk


    【解决方案1】:

    您不需要从另一个商店切片导入操作。您可以在多个存储切片的 reducer 中处理相同的查询电影操作类型。欲了解更多信息,请参阅Allow Many Reducers to Respond to the Same Action

    例如

    import { createStore, applyMiddleware, combineReducers } from 'redux';
    import thunk from 'redux-thunk';
    
    const GET_MOVIES_FULFILLED = 'GET_MOVIES_FULFILLED';
    
    function moviesLoaded(totalPages, movies) {
      return {
        type: GET_MOVIES_FULFILLED,
        payload: {
          totalPages,
          movies,
        },
      };
    }
    
    export const loadMovies = () => async (dispatch) => {
      //   const response = await fetch(url);
      //   const result = await response.json();
      // mock result
      const result = { total_pages: 0, results: [] };
      const { total_pages: totalPages, results: movies } = result;
      dispatch(moviesLoaded(totalPages, movies));
    };
    
    const rootReducer = combineReducers({
      sliceA(state = { totalPages: 0, movies: [] }, action) {
        switch (action.type) {
          case GET_MOVIES_FULFILLED:
            return action.payload;
          default:
            return state;
        }
      },
    
      sliceB(state = { status: '' }, action) {
        switch (action.type) {
          case GET_MOVIES_FULFILLED:
            if (!action.payload.movies || !action.payload.movies.length) {
              return {
                status: 'no movies',
              };
            }
          default:
            return state;
        }
      },
    });
    
    const store = createStore(rootReducer, applyMiddleware(thunk));
    
    store.dispatch(loadMovies() as any).then(() => {
      console.log(store.getState());
    });
    

    输出:

    {
      sliceA: { totalPages: 0, movies: [] },
      sliceB: { status: 'no movies' }
    }
    

    调度 GET_MOVIES_FULFILLED 操作,在 sliceAsliceB 减速器中处理它。

    如果没有电影,我们将sliceB的状态设置为{status: 'no movies'}

    【讨论】:

      猜你喜欢
      • 2015-10-28
      • 2023-01-31
      • 2014-09-17
      • 2019-05-18
      • 1970-01-01
      • 1970-01-01
      • 2018-05-30
      • 1970-01-01
      相关资源
      最近更新 更多