如何在Redux中无需回调,异步等待状态变更?
能否在异步函数中等待Redux状态变更,从而编写无回调的处理代码?
示例代码:
async function processSomething() { const results = await showModal(); // 处理返回结果 } async function showModal() { dispatch(showModalForm()); // 激活弹窗表单 // 等待弹窗关闭(监听state.active状态变化) return getState().someResults; }
实现方案
我们可以通过外部控制Promise状态结合Redux状态订阅的方式实现无回调的异步等待,同时规避Redux的序列化限制:
1. 实现可外部resolve的Promise
先封装一个工具函数,让我们能在Promise外部手动触发resolve或reject:
function createDeferred() { let resolve, reject; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); return { promise, resolve, reject }; }
2. 订阅Redux状态,等待目标状态变更
在showModal函数中,创建延迟Promise后,订阅Redux store的状态变化,当弹窗关闭的条件满足时,取消订阅并resolve Promise返回结果:
async function showModal(dispatch, getState, store) { dispatch(showModalForm()); // 触发打开弹窗的action const deferred = createDeferred(); // 订阅store的状态更新 const unsubscribe = store.subscribe(() => { const currentState = getState(); // 根据你的实际state结构,判断弹窗是否已关闭 if (!currentState.modal.active) { unsubscribe(); // 及时取消订阅,防止内存泄漏 deferred.resolve(currentState.someResults); // 返回弹窗提交的结果 } }); return deferred.promise; }
3. 规避Redux非序列化值报错
如果使用Redux Toolkit,要注意不要在Redux state中存储Promise、函数这类不可序列化的值。我们只需要在业务逻辑中使用上述延迟Promise,state里仅保存弹窗激活状态、提交结果等可序列化数据(如布尔值、字符串、普通对象),就能避免"A non-serializable value was detected in the state"这类报错。
内容的提问来源于stack exchange,提问作者Роман Коптев
相关产品推荐
相关产品推荐

