如何避免在Redux还原器中重复业务逻辑?

如何避免在Redux还原器中重复业务逻辑?,redux,Redux,假设我有一个显示给定项目问题的应用程序。用户可以打开一个问题,这意味着他们可以在屏幕上看到它,或者关闭问题,这意味着它消失了。关闭项目时,我还希望隐藏用户可见的问题 如何避免重复业务逻辑以改变减速机中的状态?我能想到三个选择,我想知道哪一个是最好的,或者有什么选择 想法一:重复代码。我将CLOSE\u项目代码复制到任何需要它的方法中,如CLOSE\u问题 const reducer = (state, action) => { switch (action.type) { ca

假设我有一个显示给定项目问题的应用程序。用户可以打开一个问题,这意味着他们可以在屏幕上看到它,或者关闭问题,这意味着它消失了。关闭项目时,我还希望隐藏用户可见的问题

如何避免重复业务逻辑以改变减速机中的状态?我能想到三个选择,我想知道哪一个是最好的,或者有什么选择

想法一:重复代码。我将
CLOSE\u项目
代码复制到任何需要它的方法中,如
CLOSE\u问题

const reducer = (state, action) => {
  switch (action.type) {
    case OPEN_PROJECT:
      state.project = action.payload.project
    case CLOSE_PROJECT:
      state.project = null
      state.issue = null
    case CLOSE_ISSUE:
      state.issue = null
  }
}
想法二:将重复使用的代码移动到助手函数中。将状态传递给helper函数,返回新状态。(注意:我使用的是immer.js,但只需将其想象为psuedo代码,实际上不会改变状态)

想法三:处理减速器外部的逻辑。具有协调多个分派调用的助手函数

const closeProject = (dispatch) {
  dispatch(closeProjectAction())
  dispatch(closeIssueAction())
}


const ReactThing = (dispatch) => {
  const handleCloseProjectClick = () => {
    closeProject(dispatcher)
  }

  return (
    <div onClick={ e => handleCloseProjectClick() }>Close</div>
  )
}
const closeProject=(调度){
分派(closeProjectAction())
分派(closeIssueAction())
}
const reacthing=(调度)=>{
const handleCloseProjectClick=()=>{
关闭项目(调度员)
}
返回(
handleCloseProjectClick()}>关闭
)
}

我认为第三个主意是最好的。但是,让所有这些业务逻辑函数在Redux之外浮动感觉很奇怪。有更好的选择吗?

这三种选择都是完全有效的。在某种程度上,这是一个如何建模逻辑以及如何抽象公共功能的问题

Redux文档中有几个部分主要解决您的问题:

在我的帖子中,我还讨论了与此相关的几个方面


另外,作为旁注:我强烈建议使用我们的,它在内部使用Immer来简化减速器设置。

我使用的是Redux starter。谢谢你的链接,看到G.K.切斯特顿的参考资料很有趣。。。但是考虑到我会阅读这些,虽然在一段时间内不一定理解它们,你会提出一个建议吗?和往常一样,“这要看情况而定”,但有30个动作(增长到50个)和一堆异步调用,最好能找到一个目标方向。理解可能会晚一点。我建议尝试将操作更多地视为“事件”,并让reducer逻辑的多个部分响应同一个操作。因此,从概念上讲,可能最接近您的示例#1。如果应用更新的过程很复杂,那么可以根据示例2将其提取到助手函数中。示例#3没有错,但没有那么多理由分派多个操作。(呵呵——我已经有一段时间没有写博文和文档了——哪个切斯特顿参考号在里面?)
const closeProject = (dispatch) {
  dispatch(closeProjectAction())
  dispatch(closeIssueAction())
}


const ReactThing = (dispatch) => {
  const handleCloseProjectClick = () => {
    closeProject(dispatcher)
  }

  return (
    <div onClick={ e => handleCloseProjectClick() }>Close</div>
  )
}