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

← →
↑