【问题标题】:How to convert the thunk action to saga如何将 thunk 动作转换为 saga
【发布时间】:2019-12-23 07:07:16
【问题描述】:

我是 redux-saga 的新手,我正在尝试制作一个简单的演示,它可以进行 API 调用并执行分页。我的理解是 redux-saga 流程应该如下工作。 Page-Size 用于限制 api 调用时显示的数据数量。

 const PAGE_SIZE = 1;

    export const fetchItems = page => (dispatch, getState) => {
      const state = getState();
      const offset = page * PAGE_SIZE;
      dispatch(setItemsCurrentPage(page));
      if (getIsPageFetched(state, page)) {
        return;
      }
      dispatch(fetchItemsRequest());
      fromItems.fetchItems({
        limit: PAGE_SIZE,
        offset,
      })
        .then((response) => {
          const pageCount = Math.ceil(response.count / PAGE_SIZE);
          dispatch(fetchItemsResponse({
            items: response.results,
            page,
            pageCount,
          }));
        })
    };

【问题讨论】:

    标签: reactjs redux action redux-saga redux-thunk


    【解决方案1】:

    selector.js

    /**
     * Direct selector to the container state domain
     */
    const selectState = () => state =>
      state.get("selectState");
    
    export {
      selectState
     };
    
    saga.js
    
         import { call, put, select } from "redux-saga/effects";
            import {selectState} from "./selector";    
               export function* fetchItems(page) {
                  try {
                  const state= yeild select(selectState())
                  const offset=page * PAGE_SIZE;
                  yield put(setItemsCurrentPage(page));
                  /**for api calls you need use **call** method**/
                  const data={limit:PAGE_SIZE,offset};
                  const requestUrl = `${url}`;
                  const options = {
                  method: "POST",
                  headers: {
                    "Content-Type": "application/json"
                  },
                  body: JSON.stringify(data)
                };
                const response = yield call(request, requestUrl, options);
                const pageCount = Math.ceil(response.count / PAGE_SIZE);
                yield put(fetchItemResponse({items:response.results,page,pageCount}))
    
                  } catch (e) {
                    yield put(LoadingError(e));
                  }
                }
    

    *note 选择器主要用于从状态中获取数据,在 thunk 中我们使用 getState() 并导航到数据,但在 saga 中您需要选择器来访问特定的状态数据。Put 用于设置要存储的数据(基本上是一个动作),call 用于 api hit。为了清楚起见,请浏览一些帖子、youtube 视频或官方文档,但我认为 thunk 更容易理解。

    【讨论】:

    • in saga you need selectors to access particular state data 选择器很有用,但不是必需的。 const state = yield select() 将返回完整状态。 /**for api calls you need use **call** method**/ 如果您想调用另一个 saga(与普通函数相反),则需要调用,它在单元测试时很有用,但如果您所做的只是调用普通函数,则不需要它.
    【解决方案2】:

    redux saga 中的等效代码如下所示:

    export function* watchFetch() {
      yield takeEvery('FETCH_ITEMS', fetchItems);
    }
    
    export function* fetchItems(action) {
      const offset = action.page * PAGE_SIZE;
      yield put(setItemsCurrentPage(page));
      if (yield select(getIsPageFetched, page)) {
        return;
      }
      yield put(fetchItemsRequest());
      const response = yield fromItems.fetchItems({
        limit: PAGE_SIZE,
        offset,
      });
      const pageCount = Math.ceil(response.count / PAGE_SIZE);
      yield put(fetchItemsResponse({
        items: response.results,
        page,
        pageCount,
      }));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 2017-11-04
      • 1970-01-01
      • 2018-02-24
      • 2017-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多