Note: This is not a post about using Thunk in your Reach Redux app. If you want to learn more about Thunk, you can check the documentation or this post Why do we need middleware for async flow in Redux? where Dan Abramov gives reasons for using thunks and async middleware, and some useful patterns for using thunks.
Redux-Thunx is a fantastic middleware for asynchronous flow in Redux. There many resources online on how to use the fetch API for networking and how to integrate Thunk. However, most of the cases use the then() method from the Fetch API to handle the returned promises rather than async or asynchronous functions.
The following code shows a basic case of a thunk function using the then() method. The dispatch() function from Thunk is inside the third chained then() method.
If you want to use the proposed ES2017 async/await syntax in your React app, you could rewrite the previous code as follows:
- remove all then() methods keeping the fetch and dispatch functions.
- convert the returned arrow function into a regular function expression. Instead of the function keyword use async function to create an async function expression. Keep the dispatch function as an argument. The async keyword defines the function as an asynchronous function, which returns an AsyncFunction object and and uses an implicit Promise object to return its result.
- create a new variable (let response in the code example) to store the asynchronous response returned by the fetch() method request. Asynchronous operations require anteposing the keyword await. As the documentation explains, the await keyword creates an await expression that pauses the execution of the asynchronous function (fetch) and waits for the passed Promise’s resolution. Upon reception, it resumes the async function's execution and returns the resolved value.
- create a new variable (let responseJSON in the code example) to store the the result of parsing the body text as
JSONwith the json() method. This method returns a promise, so use the await keyword to create an await expression.
- create a new sync function statement (dispatchLogin() in the code example) inside your async function taking as argument the async JSON response. The JSON response will be use to call the dispatch function.
- finally, call and return the dispatchLogin() function. Pass the responseJSON variable as an argument. This variable depends on the async request from fetch(). As the documentation explains, there is no await statement on the return statement, because the return value of an async function is implicitly wrapped in Promise.resolve. As an alternative to the responseJSON variable, you could directly pass as an argument the await expression declared used in the responseJSON variable.
The previous async example did not handle errors. In this case, use a try/catch statement inside the async function instead of the catch() method from the Fetch API.