Вывод результатов работы thunk в компоненте в Redux
На прошлом занятии мы отправили POST-запрос
с помощью thunk addProduct
. Давайте теперь
отобразим результаты его работы в компоненте.
Откроем наше приложение с продуктами, а в
нем файл NewProductForm.jsx
, поскольку этот
компонент ответственен за добавление нового
продукта. Посмотрим на строчки с импортом.
Заменим импорт экшена productAdded
, на
импорт thunk addProduct
:
import { addProduct } from './productsSlice'
Теперь, поскольку мы не отслеживаем в слайсе
статус 'pending'
запроса, давайте сделаем так,
чтобы пользователь смог нажать на кнопку с
сохранением продукта только один раз, ведь
нам не нужны те же самые повторные запросы.
Для этого заведем еще один локальный стейт:
const [requestStatus, setRequestStatus] = useState('idle')
Далее после обработчиков и перед функцией
onSaveProductClick
напишем код, в котором
проверим, все ли поля формы у нас заполнены
и находится ли статус запроса в 'idle'
:
const canBeSaved =
[name, desc, price, amount, sellerId].every(Boolean) &&
requestStatus === 'idle'
Затем мы изменим код для onSaveProductClick
. Во-первых
это будет асинхронная функция и она будет выполняться,
если верно вышеприведенное условие:
const onSaveProductClick = async () => {
if (canBeSaved) {}
}
Несмотря на то, что мы в слайсе не отслеживаем статус
'rejected'
, мы все равно можем вывести в
консоль ошибку, для этого воспользуемся
конструкцией try-catch
.
Также здесь мы добавим еще и finally
,
чтобы после выполнения запроса снова установить
локальный стейт в 'idle'
:
const onSaveProductClick = async () => {
if (canBeSaved) {
try {
} catch (err) {
console.error(save product error: , err)
} finally {
setRequestStatus('idle')
}
}
}
С catch
и finally
блоками мы разобрались, давайте
напишем код для блока try
. Здесь мы установим локальный
статус в 'in pogress'
, пока нам не вернется
какой-нибудь ответ в результате работы thunk,
затем отправим наш thunk addProduct
. Использовать
конструкцию try-catch
в зависимости
от типа ответа нам поможет функция RTK unwrap
,
которую он добавляет к возвращаемому промису.
Затем, если запрос был успешен мы устанавливаем
локальные стейты в их начальные состояния. Полный
код для onSaveProductClick
будет выглядеть так:
const onSaveProductClick = async () => {
if (canBeSaved) {
try {
setRequestStatus('in progress')
await dispatch(
addProduct({ name, desc, price, amount, seller: sellerId })).unwrap()
setName('')
setDesc('')
setPrice(0)
setAmount(0)
setSellerId('')
} catch (err) {
console.error('save product error: ', err)
} finally {
setRequestStatus('idle')
}
}
}
Запустим наше приложение и попробуем добавить новый продукт. Как вы видите, в случае успешного запроса поля очищаются и новый продукт добавляется в список продуктов. Также загляните в браузере в Redux DevTools и побегайте по его вкладкам, посмотрите на экшены и как меняется ваш стейт.
Откройте ваше приложение со студентами.
Откройте в нем файл NewStudentForm.jsx
.
Добавьте еще один локальный стейт requestStatus
,
и установите его изначально в 'idle'
.
Ознакомившись с материалами урока, заведите
переменную canBeSaved
, с помощью которой
кнопка сохранения новых данных студента будет
работать/не работать, в зависимости от значения
requestStatus
и от заполненности полей.
Напишите асинхронный код для onSaveStudentClick
,
который будет менять значение requestStatus
по ситуации, отправлять thunk addProduct
с данными нового студента, очищать поля
в случае успешного запроса и выводить в
консоль ошибку в случае неудачи,
как показано в уроке. Используйте для этого
конструкцию try-catch
и функцию RTK
unwrap
.
Запустите ваше приложение, добавьте нового студента и убедитесь, что все работает.