0

Although this is about the applyMiddleware implementation I accept this being a duplicate of the question referring to the spreading operator as the core of the mental issue is exactly that.

Preamble:

I don't like magic when it comes to a point where it is actually unclear why things happen. So I was looking in the actual redux implementation.

What is the problem?

Well I saw this in the implementation of 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
}

So it is actually spreading the whole store on the first level of the store object. But we just want to apply middleware and are not actually manipulating the store.

So why not just do the following?

return {
  store,
  dispatch
}

What would be the side-effects of doing store over ...store in this very specific implementation / in the scope of an app using it?

Community
  • 1
  • 1
androidavid
  • 1,258
  • 1
  • 11
  • 20
  • 1
    Possible duplicate of [What is the meaning three dots in "{...x}" \[ReactJS\]](https://stackoverflow.com/questions/42811882/what-is-the-meaning-three-dots-in-x-reactjs) – Shubham Khatri Oct 03 '17 at 08:16

3 Answers3

2

Doing store instead of ...store would completely change the meaning of the expression.

{store, dispatch} means the same as: {store: store, dispatch: dispatch}

Whereas {...store, dispatch} means expanding/merging original store object with new dispatch property.

Read more here about spread syntax.

hindmost
  • 7,125
  • 3
  • 27
  • 39
0

I've never had the chance to do a project with React, but I did watch a few videos and I know that the idea of the framework is that store is immutable(read more about immutability here), the three dots are called Spread syntax and I think that this syntax is used in shorthand instead of Object.assign

Spread in object literals

The Rest/Spread Properties for ECMAScript proposal (stage 3) adds spread properties to object literals. It copies own enumerable properties from a provided object onto a new object.

Shallow-cloning (excluding prototype) or merging of objects is now possible using a shorter syntax than Object.assign.

If you change ...store to store you will completely change the behavior of the framework. I don't know what exactly the side effects will be, we need to do some testing :)

I hope this was helpful to you to understand this piece of code better. Good Luck!

codtex
  • 6,128
  • 2
  • 17
  • 34
0

{...store, dispatch} is the same thing as Object.assign({}, store, {dispatch: dispatch}).

{store, dispatch} is the same thing as {store: store, dispatch: dispatch}.

In case you don't know what Object.assign does : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

The result is that if there is some property foo that exists on object store, on the newly created object o, in the first case you access it via o.foo, in the second case via o.store.foo.

So it makes a real difference ;)

These notations look "magical" until you learn what they do. Then you start feeling they save you a lot of time, let you write DRY and short code.

Aymeric Bouzy aybbyk
  • 2,031
  • 2
  • 21
  • 29
  • The question was already properly and clearly answered 2 times and I evaluated the answers, accepted it and edited my original question. But thanks :) – androidavid Oct 03 '17 at 08:27