Blog>
Snippets

Integrating Thunks for Async Logic

Create and dispatch a thunk using createAsyncThunk to handle asynchronous logic such as APIs requests.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thunk Async Logic</title>
<script src="https://cdn.jsdelivr.net/npm/redux@4.0.5/dist/redux.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/redux-thunk@2.3.0/dist/redux-thunk.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@reduxjs/toolkit"></script>
</head>
<body>
<div>
<button id="fetchData">Fetch Data</button>
<p id="data"></p>
</div>
<script src="script.js"></script>
</body>
</html>
This is the HTML template, including Redux and Redux Thunk via CDN, with a button to trigger the data fetch and a paragraph to display the data.
/* CSS styles are not necessary for the thunk logic example */
CSS is not included as it is not relevant to the demonstration of Thunks for async logic.
// Import createAsyncThunk and configureStore from Redux Toolkit
const { createAsyncThunk, configureStore } = window.RTK;

// Define an async function which returns a promise
const fetchDataAsync = () => fetch('https://api.example.com/data').then(response => response.json());

// Create an async thunk action
const fetchData = createAsyncThunk('data/fetch', async () => {
  const response = await fetchDataAsync();
  return response;
});

// Define the initial state
const initialState = {
  data: {},
  loading: false
};

// Create a slice with reducers generated for each action of createAsyncThunk
const dataSlice = window.RTK.createSlice({
  name: 'data',
  initialState,
  extraReducers: builder => {
    builder.addCase(fetchData.pending, state => {
      state.loading = true;
    })
    .addCase(fetchData.fulfilled, (state, action) => {
      state.loading = false;
      state.data = action.payload;
    })
    .addCase(fetchData.rejected, state => {
      state.loading = false;
    });
  }
});

// Configure the store
const store = configureStore({
  reducer: dataSlice.reducer,
  middleware: [window.RTK.getDefaultMiddleware()]
});

// Dispatch the thunk on button click
document.getElementById('fetchData').addEventListener('click', () => {
  store.dispatch(fetchData());
});

// Subscribe to store and update the UI
store.subscribe(() => {
  const { data, loading } = store.getState();
  document.getElementById('data').textContent = loading ? 'Loading...' : JSON.stringify(data, null, 2);
});
This is the JavaScript code configuring a Redux store, defining and dispatching a thunk for asynchronous API requests, and updating the UI accordingly. Redux Toolkit is accessed via the window.RTK global variable because of the CDN usage.