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関数のコードの先頭で、さらに2つの変数errorとcontentを用意します。1つ目はエラーのための変数、2つ目はリクエストステータスに応じてさまざまなコンテンツを書き込むための変数です。これはconst dataFetch = useRef(false)の前で行います:

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

次に、ProductsListコンポーネントのreturnコマンドの前に、ステータスに応じてcontentにさまざまなコンテンツが入力される条件を記述したコードブロックを書きます。まず、リクエストが送信されたときのステータス'in progress'について記述します。この場合、ユーザーにデータの読み込み中であることを通知します:

products/ProductsList.jsxif (productStatus === 'in progress') {
  content = <p>商品リストを読み込み中...</p>
}

もし読み込みが成功した場合(私たちはこれを'success'と表現しました)、取得した商品のリストを表示する必要があります。ProductCardコンポーネントを使用してmap内に表示し、プロパティとしてproductを渡します:

products/ProductsList.jsxif (productStatus === 'in progress') {
  content = <p>商品リストを読み込み中...</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>商品リストを読み込み中...</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に置き換えることを忘れないでください。