useEffectで初回取得

ボタンを押さずに取ってきたい

前回はボタンを押したら取ってくる形でした。でも商品一覧は、画面が出た時点でもう並んでいてほしいものです。押させる理由がありません。

かといって、部品の中に直接 loadItems() と書くのは駄目です。部品の中身は画面を描き直すたびに動きます。取得すると state が変わり、state が変わると描き直され、また取得が走る。止まらない輪ができます。

useEffect は描いたあとに動く

そこで useEffect を使います。React入門で出てきた、画面を描き終わったあとに動く仕掛けです。

useEffect(() => { async function load() { const res = await fetch("/api/items"); const data = await res.json(); setItems(data); } load(); }, []);

最後の [] が肝心です。これは依存配列といって、「この中身が変わったらもう一度動かす」という指定です。空のままなら変わりようがないので、最初の1回だけ動きます。書き忘れると毎回動いて、さっきの止まらない輪になります。

async を useEffect に直接付けない

次の書き方はできません。

useEffect(async () => { ... }, []);

useEffect に渡す関数は、後片付けの関数を返す約束になっています。async を付けると必ず Promise が返るので、React が後片付けだと勘違いします。だから中で async な関数を作って呼ぶ形にします。前回と同じ形です。

取れるまでは空

通信には時間がかかります。delayMs が 300 なら、最初の 0.3 秒は items が空配列のままです。その間は何も並びません。今日はそれで構いません。待っている間に何を出すかは第3章で作ります。

演習

画面が出た時点で商品一覧を取ってきて、カードを並べます。

ヒント

App.tsx
mock-api.json
App.tsx
mock-api.json
プレビュー

できているか

  • 押さなくてもカードが5枚並ぶ
  • API の商品が出ている
  • 価格も出ている