ReduxにおけるコンポーネントでのThunk実行結果の表示

前回のレッスンでは、thunk addProduct を使用してPOSTリクエストを送信しました。 今回は、その実行結果をコンポーネントに表示してみましょう。

商品管理アプリケーションを開き、新しい商品の追加を担当するコンポーネントである NewProductForm.jsx ファイルを開きます。インポート文を見てみましょう。 アクション productAdded のインポートを thunk addProduct のインポートに置き換えます:

products/NewProductForm.jsximport { addProduct } from './productsSlice'

スライスでリクエストの 'pending' ステータスを追跡していないため、 ユーザーが商品保存ボタンを一度だけ押せるようにしましょう。同じリクエストの重複を防ぐためです。 これを行うために、別のローカルステートを追加します:

products/NewProductForm.jsxconst [requestStatus, setRequestStatus] = useState('idle')

次に、ハンドラーの後、関数 onSaveProductClick の前に、 フォームのすべてのフィールドが入力されているか、およびリクエストステータスが 'idle' であるかを確認するコードを書きます:

products/NewProductForm.jsxconst canBeSaved =
  [name, desc, price, amount, sellerId].every(Boolean) &&
  requestStatus === 'idle'

次に、onSaveProductClick のコードを変更します。 まず、これは非同期関数となり、上記の条件が満たされている場合にのみ実行されます:

products/NewProductForm.jsxconst onSaveProductClick = async () => {
  if (canBeSaved) {}
}

スライスで 'rejected' ステータスを追跡していなくても、 コンソールにエラーを出力することは可能です。そのためには try-catch 構文を使用します。 また、リクエスト実行後にローカルステートを再度 'idle' に設定するために、 finally も追加します:

products/NewProductForm.jsxconst onSaveProductClick = async () => {
  if (canBeSaved) {
    try {
    } catch (err) {
      console.error('商品の保存エラー: ', err)
    } finally {
      setRequestStatus('idle')
    }
  }
}

catch と finally ブロックについては理解できたので、 try ブロックのコードを書きましょう。 ここでは、thunkの実行結果として何らかのレスポンスが返ってくるまで ローカルのステータスを 'in progress' に設定し、 その後 thunk addProduct をディスパッチします。 RTK が返すプロミスに追加する関数 unwrap を使用すると、 レスポンスのタイプに応じて try-catch 構文を利用できます。 その後、リクエストが成功した場合は、 ローカルステートを初期状態に戻します。 onSaveProductClick の完全なコードは次のようになります:

products/NewProductForm.jsxconst 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('商品の保存エラー: ', err)
    } finally {
      setRequestStatus('idle')
    }
  }
}

アプリケーションを起動し、新しい商品を追加してみましょう。 リクエストが成功すると、フィールドがクリアされ、 新しい商品が商品リストに追加されることが確認できます。 また、ブラウザの Redux DevTools を開き、 タブを切り替えてアクションやステートの変化を確認してください。

Задание 1

生徒管理アプリケーションを開いてください。 その中の NewStudentForm.jsx ファイルを開きます。 別のローカルステート requestStatus を追加し、 初期値を 'idle' に設定してください。 レッスンの内容を参考に、変数 canBeSaved を定義し、 requestStatus の値とフィールドの入力状況に応じて 新しい生徒データを保存するボタンの有効/無効を制御してください。

Задание 2

onSaveStudentClick の非同期コードを記述してください。 このコードは状況に応じて requestStatus の値を変更し、 新しい生徒データで thunk addProduct(訳注: 原文ママ。addStudentと思われる) をディスパッチし、 リクエストが成功した場合はフィールドをクリアし、 失敗した場合はエラーをコンソールに出力するようにします。 レッスンで示したように、try-catch 構文と RTK の unwrap 関数を使用してください。

Задание 3

アプリケーションを起動し、新しい生徒を追加して、 すべてが正常に動作することを確認してください。