【问题标题】:Why does redux do `{... store}` in its applyMiddleware implementation?为什么 redux 在它的 applyMiddleware 实现中做 `{... store}`?
【发布时间】:2017-10-03 07:35:02
【问题描述】:

虽然这是关于 applyMiddleware 的实现,但我认为这是与传播运算符有关的问题的重复,因为心理问题的核心正是如此。

序言:

当涉及到事情发生的原因实际上并不清楚的时候,我不喜欢魔法。所以我在查看实际的 redux 实现。

有什么问题?

嗯,我在applyMiddleware的实现中看到了这一点:

applyMiddleware.js on github

import compose from './compose'

/**
 * Creates a store enhancer that applies middleware to the dispatch method
 * of the Redux store. This is handy for a variety of tasks, such as expressing
 * asynchronous actions in a concise manner, or logging every action payload.
 *
 * See `redux-thunk` package as an example of the Redux middleware.
 *
 * Because middleware is potentially asynchronous, this should be the first
 * store enhancer in the composition chain.
 *
 * Note that each middleware will be given the `dispatch` and `getState` functions
 * as named arguments.
 *
 * @param {...Function} middlewares The middleware chain to be applied.
 * @returns {Function} A store enhancer applying the middleware.
 */
export default function applyMiddleware(...middlewares) {
  return (createStore) => (reducer, preloadedState, enhancer) => {
    const store = createStore(reducer, preloadedState, enhancer)
    let dispatch = store.dispatch
    let chain = []

    const middlewareAPI = {
      getState: store.getState,
      dispatch: (...args) => dispatch(...args)
    }
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}
return {
  ...store,
  dispatch
}

所以它实际上是在 store 对象的第一层散布了整个 store。但我们只是想应用中间件,并没有实际操作存储。

那么为什么不直接执行以下操作呢?

return {
  store,
  dispatch
}

在这个非常具体的实现中/在使用它的应用程序范围内,使用 store 而不是 ...store 会有什么副作用?

【问题讨论】:

标签: javascript redux react-redux middleware


【解决方案1】:

使用store 而不是...store 会完全改变表达式的含义。

{store, dispatch} 与:{store: store, dispatch: dispatch} 含义相同

{...store, dispatch} 表示扩展/合并原始store 对象和新的dispatch 属性。

阅读更多here关于扩展语法的信息。

【讨论】:

  • 这是完全正确的,在这种情况下是一个暂时的心理问题,混合了我这边的两种不同的东西。感谢您指出。
  • @androidavid 如果我的回答能解决你的问题,你也可以投票赞成
【解决方案2】:

我从来没有机会用React 做一个项目,但我确实看过一些视频,我知道该框架的想法是store不可变阅读更多关于不变性here),三个点被称为Spread syntax,我认为这个语法是用简写而不是Object.assign

Spread in object literals

ECMAScript 提案(第 3 阶段)的 Rest/Spread 属性添加 将属性传播到对象字面量。它复制自己的可枚举 从提供的对象到新对象的属性。

现在是浅克隆(不包括原型)或对象合并 可以使用比Object.assign 更短的语法。

如果您将...store 更改为store,您将完全改变框架的行为。我不知道到底会有什么副作用,我们需要做一些测试:)

我希望这对您更好地理解这段代码有所帮助。祝你好运!

【讨论】:

  • 是的。非常清楚,完全同意。请参阅我上面的评论。
【解决方案3】:

{...store, dispatch}Object.assign({}, store, {dispatch: dispatch}) 相同。

{store, dispatch}{store: store, dispatch: dispatch} 是一回事。

如果你不知道 Object.assign 做什么:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

结果是,如果对象store 上存在某个属性foo,则在新创建的对象o 上,在第一种情况下通过o.foo 访问它,在第二种情况下通过@ 987654331@.

所以它真的很重要;)

在您了解它们的作用之前,这些符号看起来很“神奇”。然后你开始觉得它们为你节省了很多时间,让你编写 DRY 和短代码。

【讨论】:

  • 这个问题已经正确明确地回答了 2 次,我评估了答案,接受了它并编辑了我的原始问题。但是谢谢:)
猜你喜欢
  • 2018-11-17
  • 1970-01-01
  • 2019-02-04
  • 2018-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-18
  • 2019-02-26
相关资源
最近更新 更多