我知道我不应该试图从传奇中发出雷鸣声,这与redux-saga试图做的事情背道而驰。但是我在一个相当大的应用程序中工作,大部分代码都是用thunk开发的,我们正在逐位迁移,需要从一个传奇内部发送一个thunk。 thunk无法更改,因为它被用在其他部分(一个返回一个promise的thunk),所以它会打破很多东西。
configureStore:
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!
个日志。 second!
永远不会发生。
PS:我没有收到任何错误或警告。
答案 0 :(得分:6)
您使用syncItems
错误。关键是syncItems
返回的函数需要传递给dispatch
,而不是syncItems
本身。正确的用法是:
yield put(syncItems());
我在博文Idiomatic Redux: Why use action creators?(基于an example gist I put together)中展示了如何将值传递到dispatch
的视觉比较。以下是示例:
// 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
,因为您是从传奇而不是连接的组件发送的。
答案 1 :(得分:0)
使用https://github.com/czewail/bind-promise-to-dispatch包
在saga func中添加解析和拒绝参数程序
然后使用此程序包func包装this.props.dispatch
那么您可以将其与诺言一起使用
答案 2 :(得分:0)
如果您阅读了 redux-saga 的文档并专门调用和放置:
<块引用>fn:Function - 生成器函数,或普通函数返回 Promise 作为结果,或任何其他值。
<块引用>创建一个效果描述,指示中间件将动作放入提供的通道中。
从技术上讲,thunk 返回一个 Promise,这就是为什么您可以 await
分派 thunk:
export declare type AsyncThunkAction<Returned, ThunkArg, ThunkApiConfig extends AsyncThunkConfig> = (dispatch: GetDispatch<ThunkApiConfig>, getState: () => GetState<ThunkApiConfig>, extra: GetExtra<ThunkApiConfig>) => Promise<ReturnType<AsyncThunkFulfilledActionCreator<Returned, ThunkArg>> | ReturnType<AsyncThunkRejectedActionCreator<ThunkArg, ThunkApiConfig>>> & {
abort(reason?: string): void;
requestId: string;
arg: ThunkArg;
};
这意味着您可以执行以下操作来从 saga 中发送 thunk:
yield put(
yield call(syncItems)
);
call
方法返回 action
saga 的 redux syncItems
,put
方法将使用它来调度您的操作。