如何从传奇中发送 thunk? [英] How to dispatch a thunk from a saga?
问题描述
我知道我不应该试图从 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屋!