Применение статуса запроса в Redux
На прошлых занятиях мы с помощью дополнительных
редьюсеров описали, что делать нашему приложению,
если fetchProducts отправляет при запросе
экшены pending, fulfilled и
rejected. Теперь мы можем
показать пользователю на какой стадии
сейчас загрузка данных.
Давайте откроем наше приложение с
продуктами, а в нем файл ProductsList.jsx.
Первое, что мы сделаем, это создадим отдельный
компонент для карточки продукта ProductCard.
Сделаем это сразу после строчек импорта перед
функцией ProductsList. В качестве пропса
передадим ему product:
const ProductCard = ({ product }) => {
return ()
}
А теперь в пустые круглые скобочки return
перенесем весь код для отображения данных
продукта из dispProducts:
const ProductCard = ({ product }) => {
return (
<div key={product.id} className="product-excerpt">
<h3>{product.name}</h3>
<SellerOfProd sellerId={product.seller} />
<p>{product.desc.substring(0, 100)}</p>
<UserReactions product={product} />
<Link to={`/products/${product.id}`} className="link-btn">
view
</Link>
</div>
)
}
И уберем в ProductsList оставшуюся строчку
кода. Она нам больше не нужна:
const dispProducts = products.map((product) => ())
А теперь в начале кода функции ProductsList
заведем еще пару переменных, error и
content. Первая у нас будет для ошибки,
во вторую мы будем записывать то или иное
содержимое в зависимости от статуса запроса.
Сделаем это перед const dataFetch = useRef(false):
const error = useSelector((state) => state.products.error)
let content
Теперь перед командой return компонента
ProductsList напишем блок кода
с условиями, при которых в content будет
заноситься то или иное содержимое в
зависимости от статуса. Первым мы опишем
статус 'in progress' - когда наш запрос
отправлен. В этом случаем мы сообщим
пользователю, что идет загрузка данных:
if (productStatus === 'in progress') {
content = <p>Products list loading ...</p>
}
Если наша загрузка прошла успешно (мы обозначали
это как 'success'), то нам нужно вывести
список полученных продуктов. Выведем его
в map при помощи компонента ProductCard,
которому пропсом передадим product:
if (productStatus === 'in progress') {
content = <p>Products list loading ...</p>
} else if (productStatus === 'success') {
content = products.map((product) => (
<ProductCard key={product.id} product={product} />
))
}
И последний статус, который у нас имеется -
это 'fail'. Добавим и его. Используем здесь
переменную error, в которую мы выше записали
ошибку из стейта:
if (productStatus === 'in progress') {
content = <p>Products list loading ...</p>
} else if (productStatus === 'success') {
content = products.map((product) => (
<ProductCard key={product.id} product={product} />
))
} else if (productStatus === 'fail') {
content = <div>{error}</div>
}
И последним шагом мы в блоке кода для return
заменим старый {dispProducts} на {content}.
Запустим наше приложение, кликнем в меню
по 'Products'. Все работает. Видим,
что примерно 2 секунды (как мы и
установили на сервере) у нас под формой
добавления продукта висит надпись
'Products list loading ...',
а потом появляется список продуктов.
Откройте ваше приложение со студентами.
Откройте в нем файл StudentsList.jsx.
Создайте в нем новый компонент
StudentCard. Перенесите в него код из
dispStudents, как показано в уроке.
Создайте в функции StudentsList
переменные error и content. Присвойте
переменной content содержимое в
зависимости от статуса запроса. Не
забудьте заменить в возвращаемой верстке
старый dispStudents на content.