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 명령 앞에 조건부 코드 블록을 작성하여 상태에 따라 content에 다른 내용이 들어가도록 하겠습니다. 먼저 'in progress' 상태를 설명하겠습니다 - 우리 요청이 전송되었을 때. 이 경우 사용자에게 데이터 로드 중임을 알리겠습니다:

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

로드가 성공적으로 완료되면(이를 'success'로 표시했습니다), 획득한 제품 목록을 표시해야 합니다. ProductCard 컴포넌트를 사용하여 map 안에 표시하겠습니다. 프롭으로 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에 내용을 할당하세요. 반환되는 마크업에서 기존 dispStudents를 content로 바꾸는 것을 잊지 마세요.