我想在redux存储中成功完成一个操作后,在屏幕上弹出一个窗口。
我尝试的第一件事是等待调度并检查错误字段
MyComponent.jsx
...
const error = useSelect(selectError())
const handleSubmit = async () => {
await dispatch(myAction(...)))
if(!error)
setIsPopupOpen(true);
}
...
我意识到这不起作用,因为函数范围中的错误是在组件的初始呈现中定义的,不会反映redux存储中的更改。这导致了以下解决方法。
MyComponent.jsx
...
const error = useSelect(selectError())
const [actionCompleted, setActionCompleted] = useState();
const handleSubmit = async () => {
await dispatch(myAction(...)))
setActionCompleted(true)
}
useEffect(() => {
if(actionCompleted) {
if(!error)
setIsPopupOpen(true);
setActionCompleted(false);
}
}, [error, actionCompleted])
...
但这显然更多的是一种变通方法,而不是一种实际的解决方案。我考虑将操作结果添加到存储切片的状态中,并采用了以下方法。
StoreSlice.js
const initialState = {
...
actionStatus: 'idle',
...
}
createSlice({
...
myAction: (state, action) => {
if (/* business logic */ ) {
state.error = 'some error'
state.actionStatus = 'failure'
}
},
clearMyActionStatus: (state) => {
state.actionStatus = 'idle'
}
})
MyComponent.jsx
const error = useSelect(selectError())
const [actionCompleted, setActionCompleted] = useState();
const handleSubmit = () => {
dispatch(myAction(...)))
}
useEffect(() => {
if(actionStatus === 'success') {
setIsPopupOpen(true)
dispatch(clearActionStatus());
}
}, [actionStatus])
但这对我来说似乎是错误的,在阅读后添加一个动作来重置动作状态似乎很笨拙,不像redux中通常使用的动作,但我可能错了。
这个问题似乎让我感到困惑,因为这似乎是一个失败的常见情况,但我提出的所有解决方案似乎都过于复杂。
有没有更简单的方法来处理这种情况,如果没有,哪种方法被认为是最好的?
是否需要调用setIsPopupOpen(true)
才能使Popup工作?或者你可以只跟踪Redux内部的Popup打开状态吗?这取决于你的Popup实现,但我会选择这样的东西:
- 在Redux中具有类似"popUpVisible"的布尔值
- 如果您的操作得到处理,请设置为true
- 在弹出菜单中选择
popUpVisible
,并使用它来显示/隐藏组件(将其保留在DOM中,但只更改可见性、z索引-无论需要什么( - 如果Popup关闭,则调度一个将
popUpVisble
更改为false的操作