我在React / Redux中的一些实现有以下问题。
单击按钮后,将调用特定的redux操作,并在屏幕上显示带有通知的div。您可以通过单击该div上的(X)符号(另一个redux操作)来关闭此通知,或者通知将在5秒后自动关闭。单击(x)应取消自动操作。
actions:
const OPEN = 'show_notification';
const CLOSE = 'close_notification';
const CLOSE_AUTO = 'close_auto';
function showNotification(data) {
return {
type: 'OPEN',
data
}
}
function closeNotification(index) {
return {
type: 'CLOSE',
index
}
}
function closeAuto() {
return {
type: 'CLOSE_AUTO'
}
}
epics:
import (...)
closeNotificationAuto = action$ => action
.filter(action => action.type === OPEN)
.mergeMap(action => action
.delay(5000)
.map( () => closeAuto)
.takeUntil(action$.ofType(CLOSE))
}
无论如何,当屏幕上显示两个通知时,操作=== CLOSE正在关闭第一个,并取消另一个的延迟()。
没有发布我的整个代码,因为问题就在这里,在史诗中。无法实现解决方案:
当点击(x)时,特定通知已关闭,但另一个(例如3秒的时间)仍然可见,并在另外2秒后自动隐藏。
有任何帮助!
答案 0 :(得分:1)
史诗中的代码是不完整的,所以它并不完全清楚(mergeMap内部会发生什么?)。但我确实看到了一个问题,即你的takeUntil
位于顶级可观察链上,这意味着它不会取消那个特定的延迟,它也会停止听取任何行动。
相反,您需要在mergeMap
,switchMap
等内容中单独延迟和取消匹配的操作。这通常称为“隔离观察者链”。
这可能是这样的:
const closeNotificationAuto = action$ =>
action$
.ofType(OPEN)
.mergeMap(action =>
Observable.of(action)
.delay(5000)
.map(() => closeAuto())
.takeUntil(action$.ofType(CLOSE))
);
这个模式,然后过滤flatMap(mergeMap,switchMap等),就是你的大部分史诗的样子。
关于下面的评论,您可能希望在takeUntil
通知程序中添加一个过滤器,以便仅采取以某种方式唯一标识它的CLOSE操作。
请参阅https://stackoverflow.com/a/48452283/1770633
const closeNotificationAuto = action$ =>
action$
.ofType(OPEN)
.mergeMap(action =>
Observable.of(action)
.delay(5000)
.map(() => closeAuto())
.takeUntil(
action$.ofType(CLOSE).filter(a => a.something === action.something)
)
);
如果每个都没有可用的某种唯一ID,则需要创建并包含一个。