Введение в 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.