Введение в thunks в Redux

В предыдущей главе мы организовали работу сервера, базы данных и клиента для обмена данными. Теперь нам необходимо навести последний мостик, который поможет нашему 'синхронно' организованному Redux приложению взаимодействовать с асинхронным клиентом, которого мы создали на последнем уроке предыдущей главы, чтобы отправлять запросы и получать необходимые данные в ответе.

Как мы помним из первых уроков предыдущего раздела, Redux ничего не знает о работе с асинхронной логикой и для этого мы будем использовать thunk middleware. Этот middleware позволяет работать с отправленными actions, использовать в коде нашего thunk dispatch и getState методы store, а также помогать методу dispatch работать не только с обычными JS объектами, но и с такими сущностями, как функции и промисы.

Обычно thunk-функция вызывается с двумя аргументами dispatch и getState (при необходимости), которыми можно пользоваться в теле этой функции. С помощью нее можно отправлять обычные экшены. Также ее можно отправлять через store.dispatch. Пример такой функции приведен ниже:

const changeColorThunk = (dispatch, getState) => { const colorBefore = getState() console.log(`Old Color: ${colorBefore.color}`) dispatch(changeColor()) const colorAfter = getState() console.log(`New Color: ${colorAfter.color}`) } store.dispatch(changeColorThunk)

Давайте теперь откроем наше приложение с продуктами. Первое, что мы должны получить от сервера при запуске приложения - это список продуктов. Так как обычно thunks пишутся в слайс-файлах, то мы откроем файл productsSlice.js.

Радостная новость заключается в том, что нам не надо возиться с установкой Redux Thunk, так как функция configureStore из RTK уже сделает это за нас. Поэтому просто добавим createAsyncThunk в импорт в файле:

import { createSlice, nanoid, createAsyncThunk } from '@reduxjs/toolkit'

Добавим также в импорт и наш клиент:

import { client } from '../../api/client'

А теперь при помощи createAsyncThunk создадим наш первый thunk для получения продуктов, сделаем это сразу после объявления объекта initialState:

export const fetchProducts = createAsyncThunk()

Первым параметром createAsyncThunk будет принимать строку для типа генерируемого action, а вторым - колбэк-функцию для payload, которая в результате вернет либо данные, либо промис с ошибкой (смотрите файл client.js). В коде функции мы вызываем client.get и передаем ему путь, который мы указали на сервере (посмотрите принимаемые параметры http.get в server.js):

export const fetchProducts = createAsyncThunk( 'products/fetchProducts', async () => { const response = await client.get('/fakeServer/products') return response.data } )

Откройте ваше приложение со студентами. Откройте в нем файл studentsSlice.js. Импортируйте в него функцию createAsyncThunk для создания thunk, а также client для отправки API запросов на сервер.

Сразу после объявления объекта initialState с помощью createAsyncThunk создайте thunk fetchStudents для получения списка студентов, который будет отправлять GET-запрос по адресу '/fakeServer/students', указанный у вас в файле server.js, и возвращать response.data, как показано в материалах урока. В качестве первого параметра для createAsyncThunk укажите строку 'students/fetchStudents' для типа action.



Чат с GPT Компилятор