Handling Asynchronous Actions with Middleware
Show how to dispatch actions that handle API calls and process the resolved data with redux-thunk in Redux version 5.0.0.
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
// Action Types
const FETCH_DATA_BEGIN = 'FETCH_DATA_BEGIN';
const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS';
const FETCH_DATA_FAILURE = 'FETCH_DATA_FAILURE';
// Action Creators
const fetchDataBegin = () => ({
type: FETCH_DATA_BEGIN
});
const fetchDataSuccess = data => ({
type: FETCH_DATA_SUCCESS,
payload: { data }
});
const fetchDataFailure = error => ({
type: FETCH_DATA_FAILURE,
payload: { error }
});
// Thunk Middleware for Async Action
const fetchData = url => {
return dispatch => {
dispatch(fetchDataBegin());
return fetch(url)
.then(handleErrors)
.then(res => res.json())
.then(json => {
dispatch(fetchDataSuccess(json));
return json;
})
.catch(error => dispatch(fetchDataFailure(error)));
};
};
// Handle HTTP errors
const handleErrors = response => {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
};
// Reducer
const rootReducer = (state = {}, action) => {
switch (action.type) {
case FETCH_DATA_BEGIN:
return { ...state, loading: true, error: null };
case FETCH_DATA_SUCCESS:
return { ...state, loading: false, data: action.payload.data };
case FETCH_DATA_FAILURE:
return { ...state, loading: false, error: action.payload.error, data: [] };
default:
return state;
}
};
// Store with middleware
const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
This JavaScript code sets up a Redux store with redux-thunk middleware. It defines action types, action creators, a thunk to handle an asynchronous API call, and a simple reducer. The `fetchData` function is a thunk that dispatches actions to handle the various states of an asynchronous request (begin, success, failure).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Async Redux Example</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux-thunk/2.3.0/redux-thunk.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/javascript">
// Place the JavaScript code from the previous part here
</script>
<script type="text/javascript">
// Dispatch the async action
store.dispatch(fetchData('https://jsonplaceholder.typicode.com/posts'));
// Subscribe to the store to get updates on the data
store.subscribe(() => console.log(store.getState()));
</script>
</body>
</html>
This HTML file includes the Redux and redux-thunk libraries and sets up a basic HTML structure. The JavaScript code for the Redux setup and async actions should be inserted where indicated. It also dispatches the `fetchData` thunk to initiate an API call and subscribes to the Redux store to log the state to the console when it updates.
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
#app {
margin: 20px;
padding: 20px;
border: 1px solid #ddd;
}
This CSS provides basic styling for the HTML body and the `#app` div where the Redux application will interface with the DOM.