Logging

Learn how to log the data.

Now that our UI allows us to add new recipes, we find it hard to see what actions are sent to the store. One option is to log received actions from the root reducer—but as we will see shortly, this can be problematic. Another option is to use the middleware.

The store holds connections to all the middleware functions, which receive actions before the reducers. This means they have access to any actions dispatched to the store. To test this, let’s create a simple logging middleware that will print any action sent to the store.

Go ahead and create a middleware directory and a log.js file within it:

const logMiddleware = ({ getState, dispatch }) => (next) => (action) => {
  console.log(`Action: ${ action.type }`);

  next(action);
};

export default logMiddleware;

Although the syntax can be confusing, it is required by Redux to combine middleware. However, in the innermost function we have access to the dispatch() and getState() methods from the store, the current action being processed, and the next() method, which allows us to call the next middleware in line.

Our logger prints the current action and then calls next(action) to pass on the action to the next middleware. In some cases, middleware might suppress actions or change them. That is why implementing a logger in a reducer is not a viable solution: some of the actions might not reach it.

To connect the middleware to our store, we need to modify our store.js file to use Redux’s applyMiddleware() utility function:

import { createStore, applyMiddleware } from 'redux';
import rootReducer from './reducers/root';
import logMiddleware from './middleware/log';

const store = createStore(
  rootReducer,
  applyMiddleware(logMiddleware)
);

window.store = store;

export default store;

Here is the complete implementation:

Get hands-on with 1200+ tech skills courses.