redux-Think

u

by Elizaveta Anatskata

Thunk

a thunk is a concept in programming where a function is used to delay the evaluation/calculation of an operation.

const yell        = text =>       console.log(text + '!')
const thunkedYell = text => () => console.log(text + '!')
//                          \___________________________/
//                                       |
//       	                     the thunk

thunks are a functional programming technique used to delay computation. Instead of performing some work now, you produce a function body or unevaluated expression (the “thunk”) which can optionally be used to perform the work later.

let x = 1 + 2;

let foo = () => 1 + 2;

Problem

Actions are Boring

“actions” don’t actually do anything. They’re just objects. Plain and simple and inert.

Wouldn’t it be cool if you could actually make them do something? Like, say, make an API call, or trigger other actions?

// 1. plain object
// 2. has a type
// 3. whatever else you want
{
  type: "USER_LOGGED_IN",
  username: "dave"
}
function userLoggedIn() {
  return {
    type: 'USER_LOGGED_IN',
    username: 'dave'
  };
}

redux

redux-thunk

It would be nice if an action creator could return that function – the bundle of work – instead of an action object. Something like this:

function getUser() {
  return function() {
    return axios.get('/current_user');
  };
}

If only there were some way to teach Redux how to deal with functions as actions…

Well, this is exactly what redux-thunk does: it is a middleware that looks at every action that passes through the system, and if it’s a function, it calls that function. That’s all it does.

we need to delay dispatching an action

It's time to remember about THUNK

const yell        = text =>       console.log(text + '!')
const thunkedYell = text => () => console.log(text + '!')
//                          \___________________________/
//                                       |
//       	                     the thunk

Redux will pass two arguments to thunk functions:

 

  • dispatch, so that they can dispatch new actions if they need to;  
  • getState, so they can access the current state. So you can do things like this:
function logOutUser() {
  return function(dispatch, getState) {
    return axios.post('/logout').then(function() {
      // pretend we declared an action creator
      // called 'userLoggedOut', and now we can dispatch it
      dispatch(userLoggedOut());
    });
  };
}

Set up redux-thunk in your project

First, install the package:

npm install --save redux-thunk
// You probably already import createStore from 'redux'
// You'll need to also import applyMiddleware
import { createStore, applyMiddleware } from 'redux';

// Import the `thunk` middleware
import thunk from 'redux-thunk';

// Import your existing root reducer here.
// Change this path to fit your setup!
import rootReducer from './reducers/index';

// The last argument to createStore is the "store enhancer".
// Here we use applyMiddleware to create that based on
// the thunk middleware.
const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);

Redux-Thunk Cycle

A Very Small Library Indeed

function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
		// This gets called for every action you dispatch.
		// If it's a function, call it.
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }

		// Otherwise, just continue processing this action as usual
    return next(action);
  };
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

The entirety of the redux-thunk library is this code right here 

Practice!

thanks

Redux Thunk

By Elizabeth Anatskaya