Effector 中如何正确处理异步事件的 loading 状态?
我在用 Effector 做一个请求用户数据的功能,想在请求期间显示 loading,但发现状态总是同步更新,没法反映真实加载过程。我试过在 createEvent() 里直接 set true/false,但好像时机不对。
这是我的代码:
const fetchUser = createEvent();
const $loading = createStore(false);
const $user = createStore(null);
$loading.on(fetchUser, () => true);
sample({
clock: fetchUser,
target: createEffect(async (userId) => {
const res = await api.getUser(userId);
$user.setState(res);
$loading.setState(false); // 这样写好像不规范?
})
});
这样写会导致什么问题?应该怎么正确管理 loading 状态?
问题所在:在 effect 内部手动 setState 确实不规范,而且你只处理了成功的情况,失败时 loading 永远卡住。
正确做法:直接用 effect 的
.pending属性。就三步:
1. 用 createEffect 创建异步任务,它自带 pending/done/fail 状态
2.
$loading = fetchUserFx.pending直接派生 loading 状态,Effector 会自动在 effect 开始时设为 true,完成/失败时设为 false3. 用
.on(fetchUserFx.done, ...)处理成功结果,别在 effect 内部改 store如果你还需要处理错误状态:
这样 loading、data、error 三种状态全搞定,而且是响应式的,effect 内部不用写任何 setState。
effect.pending代替手动创建的 $loading,Effector 的 effect 本身就内置了 pending 状态,会自动处理成功/失败的情况。正确的写法:
你原来写法的最大问题:如果 effect 抛异常或请求失败,loading 永远卡在 true 状态。用 effect.pending 的话,无论是 done 还是 fail 都会自动重置,不用手动管。