Redux reducer 中的副作用
Side effects in Redux reducer
Redux 减速器应该没有副作用。但是如果一个动作应该触发浏览器中的文件下载,其中内容基于商店的状态呢?这当然应该算作副作用吗?像下面这样的方法可以吗,还是我应该寻找替代方法?
case 'SAVE_GRID': {
const { json } = state
fileDownload(json, 'data.json', 'application/json')
return state
}
有库可以处理这种 "side" 效果。
例如:
- redux-observables:他们在底层使用 RX observables。
https://redux-observable.js.org/docs/basics/Epics.html
- redux-saga
除非你有非常复杂的状态转换,否则实际的 fileDownload
应该发生在 action creator 中,而不是在 reducer 中。 reducer 应该负责 merging/reducing 状态,仅此而已。
操作:
export const saveGrid = (json) => {
return (dispatch) => {
fileDownload(json, 'data.json', 'application/json')
.then(() => {
dispatch({ type: 'SAVE_GRID', json });
});
}
}
减速器:
case 'SAVE_GRID': {
return {
...state,
json: action.json
}
}
Reducers 可以 驱动效果,事实上,它们一直通过触发 UI 渲染的状态变化来实现——可以说是应用程序最重要的效果。
驱动 non-visual 效果并不常见,但至少有两种解决方案:redux-loop 和 redux-agent(我写的)。
来自各自的站点:
redux-loop:
A port of the Elm Architecture to Redux that allows you to sequence your effects naturally and purely by returning them from your reducers. https://redux-loop.js.org/
redux-agent:
Redux Agent extends React’s model to non-visual I/O: describe a network request, a storage operation, a websocket message, … and let the machine worry about performing it. Logic stays in the reducer, components stay lightweight, and it’s easy to see what state triggers which effect. https://redux-agent.org/
(引号还暗示了两者之间的主要区别:redux-loop returns 来自减速器的效果描述,从而改变了它的 API 并需要存储增强器。redux-agent 与原版 Redux 一起工作 API。)
我使用钩子 useReducer 代替 redux。我不喜欢在 action creator 中加入副作用 - 那么不清楚 action creator 的目的是什么:构建一个动作,还是 运行 side effects?
我在这里找到了满足我目的的图书馆:
Redux 减速器应该没有副作用。但是如果一个动作应该触发浏览器中的文件下载,其中内容基于商店的状态呢?这当然应该算作副作用吗?像下面这样的方法可以吗,还是我应该寻找替代方法?
case 'SAVE_GRID': {
const { json } = state
fileDownload(json, 'data.json', 'application/json')
return state
}
有库可以处理这种 "side" 效果。
例如:
- redux-observables:他们在底层使用 RX observables。
https://redux-observable.js.org/docs/basics/Epics.html
- redux-saga
除非你有非常复杂的状态转换,否则实际的 fileDownload
应该发生在 action creator 中,而不是在 reducer 中。 reducer 应该负责 merging/reducing 状态,仅此而已。
操作:
export const saveGrid = (json) => {
return (dispatch) => {
fileDownload(json, 'data.json', 'application/json')
.then(() => {
dispatch({ type: 'SAVE_GRID', json });
});
}
}
减速器:
case 'SAVE_GRID': {
return {
...state,
json: action.json
}
}
Reducers 可以 驱动效果,事实上,它们一直通过触发 UI 渲染的状态变化来实现——可以说是应用程序最重要的效果。
驱动 non-visual 效果并不常见,但至少有两种解决方案:redux-loop 和 redux-agent(我写的)。
来自各自的站点:
redux-loop:
A port of the Elm Architecture to Redux that allows you to sequence your effects naturally and purely by returning them from your reducers. https://redux-loop.js.org/
redux-agent:
Redux Agent extends React’s model to non-visual I/O: describe a network request, a storage operation, a websocket message, … and let the machine worry about performing it. Logic stays in the reducer, components stay lightweight, and it’s easy to see what state triggers which effect. https://redux-agent.org/
(引号还暗示了两者之间的主要区别:redux-loop returns 来自减速器的效果描述,从而改变了它的 API 并需要存储增强器。redux-agent 与原版 Redux 一起工作 API。)
我使用钩子 useReducer 代替 redux。我不喜欢在 action creator 中加入副作用 - 那么不清楚 action creator 的目的是什么:构建一个动作,还是 运行 side effects?
我在这里找到了满足我目的的图书馆: