为什么redux在applyMiddleware实现中做`{... store}`?

时间:2017-10-03 07:35:03

标签: javascript redux react-redux middleware

  

虽然这是关于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
}

所以它实际上是将整个商店扩展到商店对象的第一层。但我们只是想应用中间件而不是实际操作商店。

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

return {
  store,
  dispatch
}

在这个非常具体的实现/使用它的应用范围内,store...store执行的副作用是什么?

3 个答案:

答案 0 :(得分:2)

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

{store, dispatch}表示与{store: store, dispatch: dispatch}

相同

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

阅读更多关于点差语法的here

答案 1 :(得分:0)

我从来没有机会用React做一个项目,但我确实观看了一些视频,我知道框架的想法是store 不可变的阅读有关不变性的更多信息here ),这三个点称为Spread syntax,我认为这种语法用于简写而不是{{3} }

  

<强> Object.assign

     

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

     

现在正在进行浅层克隆(不包括原型)或合并对象   可能使用比Spread in object literals更短的语法。

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

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

答案 2 :(得分:0)

{...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

结果是,如果对象foo上存在某些属性store,则在新创建的对象o上,在第一种情况下,您可以通过{{1}访问它},在第二种情况下通过o.foo

所以它会产生真正的不同;)

这些符号看起来很神奇&#34;直到你了解他们做了什么。然后你开始觉得他们为你节省了很多时间,让你写下DRY和短代码。