0

I have a function from Dan Abramov`s redux course. It takes store but returning a function taking action as an argument. I know clojures but in function we didnt excute last function. addLoggingToDispatch function doesn't have action argument how does that function works?

     const addLoggingToDispatch = (store) => {
     const rawDispatch = store.dispatch;

      return (action) => {
       console.group(action.type);
       console.log('%c prev state', 'color: gray', store.getState());
       console.log('%c action', 'color: blue', action);
       const returnValue = rawDispatch(action);
       console.log('%c next state', 'color: green', store.getState());
       console.groupEnd(action.type);
       return returnValue;
      };
     };
cotut
  • 131
  • 2
  • 8

2 Answers2

2

The function that addLoggingToDispatch returns closes over the store parameter. Then, when that function is called, it gets passed an argument for action. So when that function that's returned is running, it has access to action (because that's one of its parameters) and store (because it closes over addLoggingToDispatch's parameter).

When a function is created inside another function and the inner function continues to exist after the outer function returns (because the outer function returns it, or it's been added to a list of functions like an event handler list, etc.), the inner function has an enduring link to the context in which it was created (the call to the outer function) and all of the in-scope parameters/variables of that context (store, in this example).

Here's a simpler example:

function createAdderFunction(a) {
  return function(b) {
    return a + b;
  };
}

var addFive = createAdderFunction(5);
// Now, `addFive` is a function that will add 5 to whatever you call it with
console.log(addFive(2));  // 7
console.log(addFive(37)); // 42

var addTen = createAdderFunction(10);
// And `addTen` is a function that will add 10 to whatever you call it with
console.log(addTen(15)); // 25

// `addFive` and `addTen` are separate from each other and work independently
console.log(addFive(0)); // 5
console.log(addTen(0));  // 10
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • The problem is `console.log(addFive(37))` we execute that function to work and we give argument. But my function execute returning function auto with actions arguments. That makes me confused. Where that action argument comes from – cotut Dec 28 '18 at 09:48
  • 2
    It comes from the custom, your `dispatch` method when you use it. You are writing here your custom `dispatch` method and inserting some extra logic in it. So, with closure when you feed it with a `store` as the first argument then use this dispatch method, you feed it with an `action` as the second argument. – devserkan Dec 28 '18 at 10:04
2

It looks like this function is intended to replace or wrap the dispatch method that comes with your store. The dispatch method takes an action as an argument, so it has the same signature as your return function. So wherever you actually create the store, do something like this:

const store = createStore()
store.dispatch = addLoggingToStore(store)

You might clarify this post by showing us where you actually are using addLoggingToStore. But if I understand correctly this purpose of this function is to bake in logging functionality without creating any sort of additional logging middleware. Now, whenever you call dispatch(someAction), it will run your function instead of the default provided by the redux store.

djfdev
  • 5,747
  • 3
  • 19
  • 38
  • yes exactly as you are guessed. This is full code https://github.com/gaearon/todos/blob/12-wrapping-dispatch-to-log-actions/src/configureStore.js – cotut Dec 28 '18 at 10:18