简体   繁体   English

Redux 减速器的副作用

[英]Side effects in Redux reducer

Redux reducers should be without side-effects. Redux 减速器应该没有副作用。 But what if an action should trigger the download of a file in the browser where the content is based on the state of the store?但是,如果一个动作应该触发在浏览器中下载一个文件,其中内容是基于商店的状态呢? Surely this should count as a side effect?这当然应该算作副作用吗? Would something like the following be fine or should I be looking for alternative methods?像下面这样的东西会很好还是我应该寻找替代方法?

case 'SAVE_GRID': {
  const { json } = state
  fileDownload(json, 'data.json', 'application/json')
  return state
}

Unless you have very complex state transitions, the actual fileDownload should happen in an action creator, not in the reducer.除非您有非常复杂的状态转换,否则实际的fileDownload应该发生在 action creator 中,而不是 reducer 中。 The reducer should be responsible for merging/reducing state and that is all.减速器应该负责合并/减少状态,仅此而已。

action:行动:

export const saveGrid = (json) => {
   return (dispatch) => {  
       fileDownload(json, 'data.json', 'application/json')
           .then(() => {
              dispatch({ type: 'SAVE_GRID', json });
           });
   }
}

reducer:减速器:

case 'SAVE_GRID': {
    return {
        ...state,
        json: action.json
    }
}

There are libraries to handle such "side" effects.有一些库可以处理这种“副作用”。

For example:例如:

  • redux-observables : they use RX observables under the hood. redux-observables :他们在引擎盖下使用 RX observables。

https://redux-observable.js.org/docs/basics/Epics.html https://redux-observable.js.org/docs/basics/Epics.html

  • redux-saga redux-saga

https://redux-saga.js.org/ https://redux-saga.js.org/

Reducers can drive effects, in fact they do it all the time via state changes which trigger UI rendering — arguably the application's most important effect. Reducers可以驱动效果,事实上它们一直通过触发 UI 渲染的状态变化来实现——可以说是应用程序最重要的效果。

Driving non-visual effects isn't as common but there are at least two solutions: redux-loop and redux-agent (which I wrote).驱动非视觉效果并不常见,但至少有两种解决方案:redux-loop 和 redux-agent(我写的)。

From the respective sites:从各自的网站:

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. Elm 架构到 Redux 的一个端口,它允许您通过从减速器返回它们来自然而纯粹地对效果进行排序。 https://redux-loop.js.org/ 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. Redux Agent 将 React 的模型扩展到非可视化 I/O:描述网络请求、存储操作、websocket 消息……并让机器负责执行它。 Logic stays in the reducer, components stay lightweight, and it's easy to see what state triggers which effect.逻辑留在reducer中,组件保持轻量级,很容易看出什么状态触发什么效果。 https://redux-agent.org/ https://redux-agent.org/

(The quotes also hint at a major difference between the two: redux-loop returns effect descriptions from the reducer, thereby changing its API and requiring a store enhancer. redux-agent works with vanilla Redux API.) (引号还暗示了两者之间的主要区别:redux-loop 从 reducer 返回效果描述,从而更改其 API 并需要存储增强器。redux-agent 与 vanilla Redux API 一起使用。)

I use the hook useReducer in lieu of redux.我使用钩子 useReducer 代替 redux。 I'm not a fan of putting side effects in action creators - then it is unclear what the purpose of the action creator is: build an action, or run side effects?我不喜欢将副作用放在动作创建者中 - 那么不清楚动作创建者的目的是什么:构建动作还是运行副作用?

I found a library here that fulfills my purpose:我在这里找到了一个满足我目的的图书馆:

https://github.com/Jibbedi/use-reducer-effect https://github.com/Jibbedi/use-reducer-effect

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM