コース一覧
React設計:useEffectとコンポーネント分割
時計とクリーンアップ

React設計:useEffectとコンポーネント分割

副作用、useEffect、依存配列、クリーンアップ、stateの持ち上げ、propsの受け渡し、1コンポーネント1責務、部品ツリーとフォルダ構成を扱う全19レッスンの設計コースです。JavaScript版プロフィールサイトを、状態と責務が整理されたReactアプリとして完成させます。

1
useEffectのきほん
01. 副作用とは10分
02. useEffect15分
03. 依存配列15分
04. タイトル連動15分
05. 時計とクリーンアップ15分
06. つくる - ヘッダー時計20分
07. 第7章クイズ15分
2
コンポーネント分割の設計
01. 部品ツリーで考える10分
02. stateを持ち上げる15分
03. propsのバケツリレー15分
04. 1部品1責務15分
05. フォルダ構成10分
06. つくる - ツリー整理20分
07. 第8章クイズ15分
3
総合制作
01. 全セクションReact化20分
02. メモウィジェットReact版20分
03. 命令的vs宣言的10分
04. 自由拡張20分
05. 完成と次のステップ10分

時計とクリーンアップ

effect の後始末

動きつづける副作用

これまでの副作用は、走ったらそれで終わりでした。タイマーは違います。setInterval は一度呼ぶと、止めるまでずっと動きつづけます。

JavaScript (JSX)

useEffect(() => { const id = setInterval(() => { setSeconds((s) => s + 1); }, 1000); }, []);

これでも1秒ごとに数は増えます。ただし、この部品が画面から消えたあともタイマーは動きつづけます。消えた部品の state を更新しようとして、静かに無駄な処理が積み上がります。同じ画面を何度も開け閉めすれば、タイマーはその回数だけ増えていきます。

クリーンアップ関数

そこで useEffect に渡す関数から、後始末の関数を return します。

JavaScript (JSX)

useEffect(() => { const id = setInterval(() => { setSeconds((s) => s + 1); }, 1000); return () => clearInterval(id); }, []);

返した関数はクリーンアップ関数と呼ばれ、React が次の2つのときに呼んでくれます。

  • 部品が画面から消えるとき (アンマウント)
  • 依存配列の値が変わって、effect をやり直す直前

「用意したものは自分で片づける」と覚えてください。タイマー、イベントリスナー、通信の中断など、始めたら止める必要があるものにはすべて必要です。

更新関数を使う理由

タイマーの中で setSeconds(seconds + 1) と書くと、effect が作られた時点の seconds をずっと見つづけるので 1 で止まります。setSeconds((s) => s + 1) のように前の値を受け取る形にすれば、依存配列が空でも正しく増えていきます。

つまずきどころ

return clearInterval(id) は間違いです。それは「その場で止めた結果」を返しています。return () => clearInterval(id) と、関数そのものを返します。

演習

開いてからの経過秒数を数えつづける表示を作ります。

ヒント

setInterval の戻り値はタイマーの番号です。const id = setInterval(...) と受け取っておきます

後始末は return () => clearInterval(id) です。関数そのものを返します

App.jsx
プレビュー

できているか

  • h1 に「あおいのプロフィール」と表示されている
  • 経過秒数を出す p がある
  • 2 秒たつと「開いてから 2 秒」に増えている
エディタを読み込んでいます