Използване на статус на заявка в Redux

В предишните уроци ние с помощта на допълнителни редюсери описахме какво трябва да прави нашето приложение, ако fetchProducts изпрати при заявка екшъни pending, fulfilled и rejected. Сега можем да покажем на потребителя на какъв етап се намира в момента зареждането на данни.

Нека отворим нашето приложение с продукти, а в него файла ProductsList.jsx. Първото, което ще направим, е да създадем отделен компонент за картата на продукта ProductCard. Ще направим това веднага след редовете за импорт преди функцията ProductsList. Като пропс ще му подадем product:

products/ProductsList.jsxconst ProductCard = ({ product }) => {
  return ()
}

А сега в празните кръгли скоби return ще прехвърлим целия код за показване на данни на продукта от dispProducts:

products/ProductsList.jsxconst 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 оставащия ред код. Той вече не ни трябва:

products/ProductsList.jsxconst dispProducts = products.map((product) => ())

А сега в началото на кода на функцията ProductsList ще създадем още няколко променливи, error и content. Първата ще бъде за грешка, във втората ще записваме едно или друго съдържание в зависимост от статуса на заявката. Ще направим това преди const dataFetch = useRef(false):

products/ProductsList.jsxconst error = useSelector((state) => state.products.error)
let content

Сега преди командата return на компонента ProductsList ще напишем блок код с условия, при които в content ще се вписва едно или друго съдържание в зависимост от статуса. Първо ще опишем статуса 'in progress' - когато нашата заявка е изпратена. В този случай ще съобщим на потребителя, че данните се зареждат:

products/ProductsList.jsxif (productStatus === 'in progress') {
  content = <p>Products list loading ...</p>
}

Ако нашето зареждане е преминало успешно (ние обозначихме това като 'success'), тогава трябва да изведем списък с получените продукти. Ще го изведем в map с помощта на компонента ProductCard, на който като пропс ще подадем product:

products/ProductsList.jsxif (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, в която по-горе записахме грешката от стейта:

products/ProductsList.jsxif (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 ...', а след това се появява списък с продукти.

Задание 1

Отворете вашето приложение със студенти. Отворете в него файла StudentsList.jsx. Създайте в него нов компонент StudentCard. Прехвърлете в него кода от dispStudents, както е показано в урока.

Задание 2

Създайте във функцията StudentsList променливите error и content. Присвоете на променливата content съдържание в зависимост от статуса на заявката. Не забравяйте да замените в връщания markup стария dispStudents с content.