Redux - applyMiddleware and HOC

Hello,

Could someone explain how this works? Especially the logger. Also, how is that it “knows” to log after every dispatch?


this is the original file:
Middleware and HOC Redux

Thanks

First of all, please do not post images of code. Cut and paste the code and put three backticks (the key below ESC) on the line above and three on the line below so they render well. It’s easier to read, takes less bandwidth, and is easier to cut and paste for us to talk about it.

First of all, HOCs are too big of a topic to cover here. Briefly, HOCs are an advanced React technique, a function that takes in a component and returns a modified component. There no components here so there are no HOCs. But in Redux, you do use connect, a great example of an HOC. It’s a function that takes in a component and returns a new component, modified in ways told to it by mapStateToProps and mapDispatchToProps. But there is no HOC here.

How does it know to log on each action? Because you’ve applied middleware to the store. with the statement applyMiddleware(logger). There are various middlewares you can use, but in this case you’ve created your own middleware function called logger. So, like all middleware, it will intercept any action that goes down the pipeline to the store and do what you tell it so. I’m not completely sure how that first line, but it looks like a bunch of curried functions. Here is an explanation of custom middleware. I can’t explain it better.

If that looks like a bunch of gibberish to you at this point, don’t worry about it too much. This is complex stuff. Just keep wroking at it and using it and things will start to fall into place.

Thanks Kevin for the good replay. I will rephrase my question.

  1. How do you read the curried functions line in this example…what goes in, what goes out of each one and what is the end result (specific to this example, no abstract explanation)?
  2. Does the fact that “logger” runs after each dispatch is a property of the curried function or is the implementation of Redux (the applyMiddleware(logger) or the way “compose” works)?
 const logger = store => next => action =>  {
          let result
          console.groupCollapsed("dispatching", action.type)
          console.log('prev state', store.getState())
          console.log('action', action)
          result = next(action)
          console.log('next state', store.getState())
          console.groupEnd()
          return result
      }

      const store = applyMiddleware(logger)(createStore)(
          combineReducers({ colors, sort })
      )



      const populate = compose(
        () => console.log('color count', store.getState().colors.length),
        () => store.dispatch(addColor("Big Blue", "#0000FF")),
        () => store.dispatch(addColor("Tomato", "#990000")),
        () => store.dispatch(addColor("lawn", "#009900")),
        () => store.dispatch(addColor("Party Pink", "#F142FF"))
      )

      populate()

https://rawgit.com/MoonHighway/learning-react/master/chapter-08/04-middleware/01-middleware.html

Well, you have to understand curried functions, which is not an easy subject. Maybe someone can say it better than I can:

 const logger = store => next => action =>  {
          // ...
          return result
      }

When I see that, my head gets a little twisted. But I understand it as a bunch of functions that return other functions in a chain until we get to the end. Someone smarter than me can explain the mechanics. There is probably a good youtube video about it, or maybe just expand out some of those function calls so you can see what is being passed. When I get a chance, I’ll probably do the same because now I’m curious. But the important thing is that functions are returning functions, and in that final codeblock you have access to all of them.

Does the fact that “logger” runs after each dispatch is a property of the curried function or is the implementation of Redux

Redux is allowing you to apply middleware to it, but middleware is not unique to redux. For example, I’ve written some middleware in Node. The implementation is different, but the concept is the same - you are adding a bit of software that will be a middleman, something that intercepts the chain of “goings on”.