According to Wikipedia, a ‘thunk’ is:
In computer programming, a thunk is a subroutine used to inject an additional calculation into another subroutine. Thunks are primarily used to delay a calculation until its result is needed, or to insert operations at the beginning or end of the other subroutine.
https://en.wikipedia.org/wiki/Thunk
Because Javascript runs synchronously (meaning it’ll keep executing despite not finishing the previous line of code – think: an external API call) we have to figure out a way to alter this behavior so that we can make those external API calls to allow our apps to be more versatile. If we don’t change this, our code will not work as intended, or perhaps not at all. Imagine you have a React/Redux app and you’re making an API call to get back a json object containing a list of top 10 movie and you need to map over an array within that json… but what if your array is empty? Or even worse, undefined?
We need to be able to execute code asynchronously as opposed to just synchronously.
Enter Redux Thunk – a way for you to return functions, rather than just actions within Redux.
Here’s a basic example that should make it more clear as to what’s going on:
const INCREMENT_NUMBER = 'INCREMENT_NUMBER';
function addToCount() {
return {
type: INCREMENT_NUMBER
};
}
function increment() {
return dispatch => {
setTimeout(() => {
dispatch(addToCount());
}, 1000);
};
}
Imagine calling the increment() function… You’ll see we setup a delay for 1000 milliseconds (1 second). Javascript normally wouldn’t wait around for that 1 second. Instead it would continue to attempt to execute you code and more than likely run into errors as a result. Thanks to the Thunk middleware, we can return functions instead of actions and we now can wait the 1 second.
export function fetchEmployeeInterestsNews(id) {
return (dispatch) => {
dispatch(getEmployeesInterestsNews());
fetch('/v1/employees/' + id + '/interests/newsfeed')
.then(response => response.json())
.then(data => dispatch(getEmployeesInterestsNewsSuccess(data)))
.catch(err => dispatch(fetchEmployeeInterestsNewsFailure(err)))
}
}
Above is a typical thunk that’s responsible for making an API call, then taking the returned json and dispatching it to the reducer in order to update the global store. If we attempted this without the thunk middleware, the API call wouldn’t finish in time before we attempted to pass it in as an argument to getEmployeesInterestsNewsSuccess().