我正在将一个现有的状态模型转换为Redux,这在很大程度上是无痛的。然而,我遇到的一个问题是转换“观察到的”状态ajax请求。本质上,我有一些与其他状态“链接”的ajax请求,所以无论是谁修改它们,它们都会被正确地发出。我可以通过订阅Redux商店更新来获得类似的行为,但在侦听器中启动操作感觉像是一种黑客行为
一个可能的解决方案是通过thunk模式将逻辑移动到动作创建者。问题是,我要么必须在操作之间复制获取逻辑(因为多个操作可能会修改“观察到的”状态),要么将大多数缩减器逻辑拉到操作创建者级别。动作创建者也不应该知道减缩器将如何响应已发布的动作
我可以批处理“子操作”,所以我只需要在每个操作“块”中放置适当的获取逻辑,但这似乎违反了操作生成有效状态的概念。我宁愿在行动创造者的层面上承担责任
有没有普遍接受的规则?这不是一个简单的应用程序,在这个应用程序中,当组件与之交互时会发出临时ajax请求,大多数数据在多个组件之间共享,并且请求会根据状态变化进行优化和获取
TLDR;
我希望激发ajax请求以响应状态的变化,而不是在特定操作发生时。除了在订阅侦听器中触发这些动作之外,还有没有更好的“特定于Redux”的方式来组织动作/动作创建者来模拟这种行为
使用store.subscribe()
最简单的方法是简单地使用store.subscribe()方法:
让我们先说
store.subscribe(()=>{
let state=store.getState()
如果(state.something!==prevState.something){
store.dispatch(something())
}
状态
})
您可以编写一个自定义抽象,允许您注册副作用的条件,以便以更声明的方式表达它们
使用Redux循环
您可能想看看Redux循环,它让您可以将效果(如AJAX)调用与还原器中的状态更新一起描述
通过这种方式,您可以“返回”这些效果以响应某些操作,就像您当前返回下一个状态一样:
导出默认函数缩减器(状态、操作){
开关(动作类型){
“装载开始”案例:
回路(
{…状态,加载:true},
Effects.promise(fetchDetails、action.payload.id)
);
“加载成功”案例:
返回{
状态
加载:false,
详情:action.payload
};
这种方法的灵感来自Elm体系结构
使用Redux传奇
您还可以使用Redux Saga来编写长时间运行的流程(“Saga”)它可以采取操作,执行一些异步工作,并将结果操作放入存储。Sagas会观察特定的操作,而不是状态更新,这不是您要求的,但我想我还是会提到它们以防万一。它们对于复杂的异步控制流和并发非常有效
函数*fetchUser(操作){
试一试{
const user=yield调用(Api.fetchUser,action.payload.userId);
产生put({type:“USER\u FETCH\u successed”,USER:USER});
}捕获(e){
产生put({type:“USER\u FETCH\u FAILED”,message:e.message});
}
}
函数*mySaga(){
收益率*takeEvery(“用户提取请求”,提取用户);
}
没有一条路是正确的
所有这些选项都有不同的权衡。有时人们会使用一个或两个,甚至全部三个选项,这取决于测试和描述必要逻辑的最方便方式。我鼓励您尝试所有三个选项,并选择最适合您的用例的选项