如果你使用Redux Thunk中间件,你可以将它封装在一个 action creator 中:
function addItem(id) {
return { type: 'ADD_ITEM', id };
}
function showNotification(text) {
return { type: 'SHOW_NOTIFICATION', text };
}
export function addItemWithNotification(id) {
return dispatch => {
dispatch(addItem(id));
doSomeSideEffect();
dispatch(showNotification('Item was added.');
};
}
根据对此答案的评论进行详细说明:
那么也许这对我来说是错误的模式。我不希望在 and 之间调用订阅dispatch(addItem(id))
者doSomeSideEffect()
。
在 95% 的情况下,您不必担心订阅者是否被调用。如果数据没有改变,像 React Redux 这样的绑定不会重新渲染。
放入doSomeSideEffect()
减速器是一种可接受的方法还是有隐藏的陷阱?
不,将副作用放入减速器是绝对不能接受的。这违背了 Redux 的核心前提,并且破坏了其生态系统中的几乎所有工具:Redux DevTools、Redux Undo、任何记录/重放解决方案、测试等。永远不要这样做。
如果你真的需要与一个动作一起执行副作用,并且你真的很关心订阅者只被通知一次,那么只需调度一个动作并使用 [Redux Thunk] 来“附加”一个副作用到它:
function addItem(id, item) {
return { type: 'ADD_ITEM', id, item };
}
export function addItemWithSomeSideEffect(id) {
return dispatch => {
let item = doSomeSideEffect(); // note: you can use return value
dispatch(addItem(id, item));
};
}
在这种情况下,您需要处理ADD_ITEM
不同的减速器。没有必要在不通知订阅者两次的情况下分派两个动作。
这是我仍然绝对不明白的一点。Dan 建议 thunk 中间件不能推迟订阅者通知,因为这会破坏异步请求的常见用例。这个我还是不明白。
考虑一下:
export function doSomethinAsync() {
return dispatch => {
dispatch({ type: 'A' });
dispatch({ type: 'B' });
setTimeout(() => {
dispatch({ type: 'C' });
dispatch({ type: 'D' });
}, 1000);
};
}
您希望何时通知订阅?C
当然,如果我们只在 thunk 退出时通知订阅者,对于and ,我们根本不会通知他们D
。
无论哪种方式,这对于当前的中间件架构都是不可能的。中间件并不是为了防止订阅者被解雇。
但是,您所描述的可以使用像redux-batched-subscribe这样的存储增强器来完成。它与 Redux Thunk 无关,但它会导致同步调度的任何一组操作被去抖动。这样,您将收到一个关于A
and的通知B
,以及另一个关于C
and的通知D
。也就是说,在我看来,依赖这种行为编写代码会很脆弱。