如何从传奇中发送 thunk? [英] How to dispatch a thunk from a saga?

查看:34
本文介绍了如何从传奇中发送 thunk?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我不应该试图从 sagas 中发送 thunk,这与 redux-saga 试图做的事情背道而驰.但是我在一个相当大的应用程序中工作,大部分代码都是用 thunk 编写的,我们正在逐位迁移,需要从 saga 内部发送一个 thunk.thunk 不能更改,因为它用于其他部分(返回 promise 的 thunk),因此它会破坏很多东西.

I know I shouldn't be trying to dispatch thunks from sagas, it goes against what redux-saga tries to do. But I'm working in a fairly large app and most of the code is made with thunks, we are migrating by bits and need to dispatch a thunk from inside a saga. The thunk can't be changed because it is used in other parts (a thunk that returns a promise), so it would break many things.

配置存储:

const store = createStore(
  rootReducer,
  initialState,
  compose(applyMiddleware(thunk, sagaMiddleware))
);

传奇:

// Saga (is called from a takeEvery)
function* watchWarehouseChange(action) {
  const companyId = yield select(Auth.id);

  // We use cookies here instead of localStorage so that we persist
  // it even when the user logs out. (localStorage clears on logout)
  yield call(Cookies.set, `warehouse${companyId}`, action.warehouse);

  // I want to dispatch a thunk here
  yield put.resolve(syncItems);
  // put(syncItems) doesn't work either
}

想:

export function syncItems() {
  console.log('first!');

  return dispatch => {
    console.log('second!');

    return dispatch(fetchFromBackend()).then(
      items => itemsDB.emptyAndFill(items)
    )
  }
}

每当 syncItems() 被执行时,只有 first! 记录.第二!永远不会发生.

Whenever syncItems() is executed, only first! logs. second! never happens.

PS:我没有收到任何错误或警告.

PS: I don't get any errors or warnings.

推荐答案

您使用的 syncItems 是错误的.关键是syncItems 返回的函数需要传递给dispatch,而不是syncItems 本身.正确的用法是:

You're using syncItems wrong. The key is that the function returned by syncItems needs to get passed to dispatch, not syncItems itself. The correct usage would be:

yield put(syncItems());

我在我的博客文章 惯用的 Redux:为什么使用动作创建器?(基于 我放在一起的示例要点).以下是示例:

I showed some visual comparisons of how values are passed into dispatch in my blog post Idiomatic Redux: Why use action creators? (based on an example gist I put together). Here's the examples:

// approach 1: define action object in the component
this.props.dispatch({
    type : "EDIT_ITEM_ATTRIBUTES", 
    payload : {
        item : {itemID, itemType},
        newAttributes : newValue,
    }
});

// approach 2: use an action creator function
const actionObject = editItemAttributes(itemID, itemType, newAttributes);
this.props.dispatch(actionObject);

// approach 3: directly pass result of action creator to dispatch
this.props.dispatch(editItemAttributes(itemID, itemType, newAttributes));

// parallel approach 1: dispatching a thunk action creator
const innerThunkFunction1 = (dispatch, getState) => {
    // do useful stuff with dispatch and getState        
};
this.props.dispatch(innerThunkFunction1);

// parallel approach 2: use a thunk action creator to define the function        
const innerThunkFunction = someThunkActionCreator(a, b, c);
this.props.dispatch(innerThunkFunction);

// parallel approach 3: dispatch thunk directly without temp variable        
this.props.dispatch(someThunkActionCreator(a, b, c));

在您的情况下,只需将 yield put 替换为 this.props.dispatch,因为您是从 saga 而不是连接组件调度.

In your case, just substitute yield put for this.props.dispatch, since you're dispatching from a saga instead of a connected component.

这篇关于如何从传奇中发送 thunk?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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