by Elizaveta Anatskata
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;
“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'
};
}
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.
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:
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());
});
};
}
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)
);
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