Jason Goemaat
Jason Goemaat

Reputation: 29234

What do chained arrow functions mean in redux?

Looking at the real world example I see this setting up the api middleware:

export default store => next => action => {
  const callAPI = action[CALL_API]
  if (typeof callAPI === 'undefined') {
    return next(action)
  }

What exactly is happening here? I see that configureStore is importing whatever that is and passing it to applyMiddleware from redux, but what does this kind of statement mean in js?

I assume it's exporting an anonymous function that returns a function that returns a function? Just tried this:

var a = b => c => d => {
    console.log('a:', a);
    console.log('b:', b);
    console.log('c:', c);
    console.log('d:', d);
};

a(5)(6)(7);

// outputs b: 5, c: 6, and d: 7

Upvotes: 3

Views: 827

Answers (2)

kube
kube

Reputation: 13944

Function Specialization

The arrow function notation simplifies currying in JavaScript.

Here it's just a way to do partial applications, and permits to bind arguments to the function at different times, by using Closures instead of Function.prototype.bind.

When you call applyMiddleware during Store creation, Redux will specialize your Middleware with the current Store it's been applied to.

Then it becomes a new specialized function, that only takes two arguments:

next => action

Where next is the next middleware that will be called on the Action. (Just like in Express, which popularized the concept, for request handling)

Timeline

The important thing here is that all these function specializations are done at different times.

  • store can be bound during Store creation.
  • next can be bound once it knows the Store it's been bound to, so also during Store creation, but could be updated later.
  • action is known only when you effectively dispatch an Action, which can happen any time.

The specialized middleware (the one which has been bound to the Store, and is already aware of the Next middleware function) will be reusable, and called for each new dispatched Action.

Functional Programming

These concepts (currying and partial application) come from the Functional Programming world.

Redux relies heavily on this paradigm, and the most important thing in Redux is the sidelining of Side-Effects (especially mutations).

Capturing directly the context of the function, or using a global Store via require, is a side-effect as your function will directly after its declaration be bound to this Store.

Instead Redux uses Currying to permit sort of Dependency Injection, and it results in a stateless function, that can be reused and specialized at runtime.

This way your Middleware is Loosely Coupled to the Store.

Upvotes: 5

Harkirat Saluja
Harkirat Saluja

Reputation: 8114

To understand this clearly you need to first know how middlewares work in redux. So first go through this

Now even after going through the documentation you are still confused, dont worry its a bit complicated, try reading it once again :).I understood this properly after 2-3 reads.

Now the one you mentioned in your question is a curried up ES6 syntax. If you try to convert this to vanilla javascript it would come to something like below

function (store) {
  return function (next) {
    return function (action) {
      var callAPI = action[CALL_API];
      if (typeof callAPI === 'undefined') {
        return next(action);
      }
    };
  };
};

So if you see its nothing but just chaining of functions.

Upvotes: 1

Related Questions