Ada*_*son 13 architecture ajax state asynchronous redux
我正在将现有的状态模型转换为Redux,并且它在大多数情况下都是无痛的.然而,我遇到麻烦的一点是转换"观察"状态ajax请求.基本上,我有一些ajax请求"链接"到其他状态,所以无论谁修改它们,它们总是会被正确发出.我可以通过订阅Redux商店更新来获得类似的行为,但是在侦听器中触发操作感觉就像是黑客.
一种可能的解决方案是通过thunk模式将逻辑移动到动作创建器.问题是,我要么必须重复读取整个行动的逻辑(因为多个行动可以"观察"的状态修改),或拉最减速逻辑的行动创造者的水平.动作创建者也不应该知道减速器将如何响应已发布的动作.
我可以批量"的子行动",所以我只需要把相应的取逻辑中的每个动作"块",但这似乎是违反了生产的有效状态的操作概念.我宁愿在行动创造者层面承担这个责任.
是否有任何普遍接受的规则?这不是一个简单的应用程序,在组件与之交互时进行ad hoc ajax请求,大多数数据在多个组件之间共享,并且请求被优化并获取以响应状态更改.
TLDR; 我想触发ajax请求以响应状态的变化,而不是在特定动作发生时.除了在订阅侦听器中触发这些操作之外,是否有更好的"Redux特定"方式来组织action/actionCreators来模拟此行为?
Dan*_*mov 20
store.subscribe()最简单的方法是简单地使用store.subscribe()方法:
let prevState
store.subscribe(() => {
let state = store.getState()
if (state.something !== prevState.something) {
store.dispatch(something())
}
prevState = state
})
Run Code Online (Sandbox Code Playgroud)
您可以编写一个自定义抽象,让您注册副作用的条件,以便更加声明地表达它们.
您可能希望查看Redux Loop,它可以让您在reducers中描述效果(例如AJAX)调用以及状态更新.
通过这种方式,您可以"返回"这些效果以响应某些操作,就像您当前return处于下一个状态一样:
export default function reducer(state, action) {
switch (action.type) {
case 'LOADING_START':
return loop(
{ ...state, loading: true },
Effects.promise(fetchDetails, action.payload.id)
);
case 'LOADING_SUCCESS':
return {
...state,
loading: false,
details: action.payload
};
Run Code Online (Sandbox Code Playgroud)
这种方法的灵感来自Elm Architecture.
您还可以使用终极版传奇,让你写长时间运行的进程("传奇"),可以采取行动,执行一些异步工作,并把结果行动商店.Sagas观看特定的动作,而不是状态更新,这不是你要求的,但我想我还是会提到它们以防万一.它们非常适用于复杂的异步控制流和并发.
function* fetchUser(action) {
try {
const user = yield call(Api.fetchUser, action.payload.userId);
yield put({type: "USER_FETCH_SUCCEEDED", user: user});
} catch (e) {
yield put({type: "USER_FETCH_FAILED",message: e.message});
}
}
function* mySaga() {
yield* takeEvery("USER_FETCH_REQUESTED", fetchUser);
}
Run Code Online (Sandbox Code Playgroud)
所有这些选项都有不同的权衡.有时人们使用一个或两个,甚至全部三个,这取决于最便于测试和描述必要逻辑的内容.我鼓励你尝试这三种方法并选择最适合你用例的方法.
对我来说,拥有订阅状态更新和启动 Ajax 请求(触发操作)的模块似乎很好,因为它让 store/reducer 牢牢负责触发请求。在我的大型应用程序中,所有 Ajax 请求和其他异步行为都是以这种方式完成的,因此所有操作都可以只是有效负载,没有“操作创建者”的概念。
如果可能,请避免级联同步操作。我的异步处理程序从不同步触发操作,而是仅在请求完成后才触发操作。
在我看来,这是一种比异步操作创建器更实用的方法,您可能喜欢也可能不喜欢!