Search code examples
javascriptreduxreact-reduxmiddleware

Why does redux do `{... store}` in its applyMiddleware implementation?


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?


Solution

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