redux-observable 调度操作
redux-observable dispatch actions
我需要使用 redux-observable
以某种顺序分派一些动作,但是,分派只需要最后一个动作。请看例子:
export const fetchClientsEpic = (action$, { dispatch }) =>
action$
.ofType(fetchClients)
.mapTo(fetchClientsPending(true))
.mergeMap(() => {
return ajax
.getJSON('some/get/clients/api')
.map((clients: IClient[]) => {
return fetchClientsSuccess(
map(clients, (client, index) => ({
key: index,
...client,
})),
);
});
});
fetchClientsSuccess
是与客户一起发送的,但 fetchClientsPending
不是,我完全不明白为什么。我可以使用 dispatch
因为我在参数中得到它,但我觉得这不是好的解决方案(?)。我想应该在流中完成。我从 RxJs 和 redux-observable 开始。有可能吗?
运算符是 Observable 链,其中一个流的输入是另一个流的输出。因此,当您使用 mapTo
时,您是在将一个操作映射到另一个操作。但是然后你的 mergeMap
映射那个 Pending 动作并将它映射到另一个内部 Observable 执行 ajax 等等,有效地抛弃了 Pending 动作。所以把 RxJS 想象成一系列数据流经的管道(a stream)
虽然没有灵丹妙药,但在这种特殊情况下,您可以通过在内部 Observable
的末尾使用 startWith
来实现您想要实现的目标
export const fetchClientsEpic = (action$, { dispatch }) =>
action$
.ofType(fetchClients)
.mergeMap(() => {
return ajax
.getJSON('some/get/clients/api')
.map((clients: IClient[]) => {
return fetchClientsSuccess(
map(clients, (client, index) => ({
key: index,
...client,
})),
);
})
.startWith(fetchClientsPending(true)); // <------- like so
});
这实际上与使用 concat
和 of(action) first
相同,只是 shorthand.
export const fetchClientsEpic = (action$, { dispatch }) =>
action$
.ofType(fetchClients)
.mergeMap(() => {
return Observable.concat(
Observable.of(fetchClientsPending(true)),
ajax
.getJSON('some/get/clients/api')
.map((clients: IClient[]) => {
return fetchClientsSuccess(
map(clients, (client, index) => ({
key: index,
...client,
})),
);
})
);
});
也就是说,我建议不要同步分派另一个操作来设置抓取挂起的状态,而是依赖原始 fetchClients
操作本身来达到相同的效果。您的减速器应该假设,如果看到这样的操作,无论如何仍然会以某种方式开始获取。这为您节省了样板文件并在 micro-perf 上有所帮助,因为您不需要 运行 通过 reducer、epics 和重新渲染两次。
虽然没有规则,所以如果您对此有强烈的感觉,那就去吧:)
我需要使用 redux-observable
以某种顺序分派一些动作,但是,分派只需要最后一个动作。请看例子:
export const fetchClientsEpic = (action$, { dispatch }) =>
action$
.ofType(fetchClients)
.mapTo(fetchClientsPending(true))
.mergeMap(() => {
return ajax
.getJSON('some/get/clients/api')
.map((clients: IClient[]) => {
return fetchClientsSuccess(
map(clients, (client, index) => ({
key: index,
...client,
})),
);
});
});
fetchClientsSuccess
是与客户一起发送的,但 fetchClientsPending
不是,我完全不明白为什么。我可以使用 dispatch
因为我在参数中得到它,但我觉得这不是好的解决方案(?)。我想应该在流中完成。我从 RxJs 和 redux-observable 开始。有可能吗?
运算符是 Observable 链,其中一个流的输入是另一个流的输出。因此,当您使用 mapTo
时,您是在将一个操作映射到另一个操作。但是然后你的 mergeMap
映射那个 Pending 动作并将它映射到另一个内部 Observable 执行 ajax 等等,有效地抛弃了 Pending 动作。所以把 RxJS 想象成一系列数据流经的管道(a stream)
虽然没有灵丹妙药,但在这种特殊情况下,您可以通过在内部 Observable
的末尾使用startWith
来实现您想要实现的目标
export const fetchClientsEpic = (action$, { dispatch }) =>
action$
.ofType(fetchClients)
.mergeMap(() => {
return ajax
.getJSON('some/get/clients/api')
.map((clients: IClient[]) => {
return fetchClientsSuccess(
map(clients, (client, index) => ({
key: index,
...client,
})),
);
})
.startWith(fetchClientsPending(true)); // <------- like so
});
这实际上与使用 concat
和 of(action) first
相同,只是 shorthand.
export const fetchClientsEpic = (action$, { dispatch }) =>
action$
.ofType(fetchClients)
.mergeMap(() => {
return Observable.concat(
Observable.of(fetchClientsPending(true)),
ajax
.getJSON('some/get/clients/api')
.map((clients: IClient[]) => {
return fetchClientsSuccess(
map(clients, (client, index) => ({
key: index,
...client,
})),
);
})
);
});
也就是说,我建议不要同步分派另一个操作来设置抓取挂起的状态,而是依赖原始 fetchClients
操作本身来达到相同的效果。您的减速器应该假设,如果看到这样的操作,无论如何仍然会以某种方式开始获取。这为您节省了样板文件并在 micro-perf 上有所帮助,因为您不需要 运行 通过 reducer、epics 和重新渲染两次。
虽然没有规则,所以如果您对此有强烈的感觉,那就去吧:)