Redux sagas 仅在多次分派相同 id 时获取一次 [英] Redux sagas Fetch only once when same id is dispatched multiple times

查看:51
本文介绍了Redux sagas 仅在多次分派相同 id 时获取一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从我的 API 中获取一个用户并将其存储在我的状态中,这样我就不必再次获取它.问题是多个组件同时请求用户导致多个并发获取请求.

I’m getting a user from my API and store it in my state so I don’t have to fetch it again. Problem is that multiple components requests the user at the same time resulting in multiple concurrent fetch requests.

有什么好的模式可以避免这种情况吗?

Is there a good pattern to avoid this?

这是我的传奇

function* watchUserRequests() {
    yield takeEvery(actionTypes.USER_REQUESTED, userRequested);
}

function* userRequested(action) {
    const {id} = action.payload;
    let user = yield select(state => state.users.all[id]);
    // cancel if user exists      
    if (user) return;
    user = yield call(userApi.get, id);
    yield put(userActions.userLoaded(id, banner));
}

动作

export function userRequested(id) {
    return {type: types.USER_REQUESTED, payload: {id}};
}

export function userLoaded(id, user) {
    return {type: types.USER_LOADED, payload: {id, user}};
}

推荐答案

这是我在另一个传奇中解决这个问题的方法.这里的类型"可以忽略

This is how I solved this problem in another saga. The "type" here can be ignored

  • 在 ids 对象中累积请求的 id:
  • 调度操作以获取所有累积的 ID
  • 去抖动 50 毫秒
  • 在等待中...向 ids 对象添加新的 ID
  • 在等待中...取消获取任务,为您提供 50 毫秒的新时间
  • 提交获取
  • 清除任务和 ID

代码:

let ids = {};
let tasks = {};

function* watchCounterRequests() {
  yield takeEvery(actionTypes.COUNTER_REQUESTED, accumulate);
}

function* watchCounterFetchRequests() {
  yield takeEvery(actionTypes.COUNTER_FETCH_REQUESTED, counterFetchRequested);
}

function* accumulate(action) {
  const {id, type} = action.payload;
  if (!ids[type]) ids[type] = {};

  ids[type][id] = true;
  if (tasks[type]) {
    yield cancel(tasks[type]);
  }
  tasks[type] = yield fork(fetchCounters, type);
}

function* fetchCounters(type) {
  yield call(delay, 50);

  yield put({
    type: actionTypes.COUNTER_FETCH_REQUESTED,
    payload: {type: type, ids: Object.keys(ids[type])},
  });

  delete ids[type];
  delete tasks[type];
}

function* counterFetchRequested(action) {
  const {ids, type} = action.payload;
  let typeName = type + 'Ids';
  let req = {
    [typeName]: ids
  };
  yield put(counterActions.loadCounters(req));
}

export default [watchCounterRequests, watchCounterFetchRequests];

其中大部分来自这里:https://marmelab.com/blog/2016/10/18/using-redux-saga-to-deduplicate-and-group-actions.html

这篇关于Redux sagas 仅在多次分派相同 id 时获取一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆