Understanding compose functions in redux

Harkirat Saluja picture Harkirat Saluja · Dec 28, 2016 · Viewed 35.3k times · Source

I was trying to create a store in redux for which I am currently using following syntax:-

const middlewares = [
  thunk,
  logger
]

const wlStore = createStore(
  rootReducer,
  initialState
  compose(applyMiddleware(...middlewares))
)

The above works fine for me and I can access the store, but I lately I bumped into another syntax:-

const wlStore=applyMiddleware(thunk,logger)(createStore)(rootReducer)

Both of them seem to be doing the same job.

Is there any reason because of which I should prefer one over another? Pros/Cons?

Answer

therewillbecode picture therewillbecode · Dec 28, 2016

Improved readability and convenience are the main advantages of using compose.

Compose is used when you want to pass multiple store enhancers to the store. Store enhancers are higher order functions that add some extra functionality to the store. The only store enhancer which is supplied with Redux by default is applyMiddleware however many other are available.

Store Enhancers are Higher Order Functions

What are higher order functions? Paraphrased from the Haskell docs:

Higher order functions can take functions as parameters and return functions as return values. A function that does either of those is called a higher order function

From the Redux docs:

All compose does is let you write deeply nested function transformations without the rightward drift of the code. Don’t give it too much credit!

So when we chain our higher order functions (store enhancers) instead of having to write

func1(func2(func3(func4))))

we could just write

compose(func1, func2, func3, func4)

These two lines of code do the same thing. It is only the syntax which differs.

Redux Example

From the Redux docs if we don't use compose we would have

finalCreateStore = applyMiddleware(middleware)(
      require('redux-devtools').devTools()(
       require('redux-devtools').persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))()
     )
     )(createStore);

Whereas if we use compose

finalCreateStore = compose(
    applyMiddleware(...middleware),
    require('redux-devtools').devTools(),
    require('redux-devtools').persistState(
      window.location.href.match(/[?&]debug_session=([^&]+)\b/)
    )
  )(createStore);

To read more about Redux's compose function click here