この記事では、React Hooksの一覧と用途を紹介します。
React Hooksは、Reactコンポーネントの開発をよりシンプルにするための強力な機能です。
Hook一覧
知っておいた方がいいリスト
- useState
- useEffect
- useContext
- useReducer
- useCallback
- useMemo
- useRef
多分知ってなくてもなんとかなる(ていうかこんなのあるんだ)リスト
- useImperativeHandle
- useLayoutEffect
- useDebugValue
今回は知っておいた方がいいリストについての紹介をしていきます。
useState
useStateは、関数コンポーネント内で状態を管理するためのHookです。
状態の初期値を引数に取り、現在の状態とそれを更新するための関数を返します。
以下のサンプルではボタンを押した回数をステートで管理して表示する例を示しています。
使用する際の注意点は
- 破壊的な変更はできない
配列やオブジェクトを管理している場合は注意が必要です。具体的には配列のpushで値を追加しても正しく反映されないです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const addItem = (item) => { items.push(item); // 破壊的な変更 setItems(items); }; return ( <div className="App"> <ul> {items.map((item, index) => ( <li key={index}>{item}</li> ))} </ul> <button onClick={() => addItem("New item")}>Add item</button> </div> ); |
配列やオブジェクトを更新する時にはスプレッド演算子を使用しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
const [items, setItems] = useState([]); const addItem = (item) => { setItems([...items, item]); // 破壊的な変更を回避する }; return ( <div className="App"> <ul> {items.map((item, index) => ( <li key={index}>{item}</li> ))} </ul> <button onClick={() => addItem("New item")}>Add item</button> </div> ); |
- 状態の変更は非同期であり、更新された状態を他の処理ですぐに利用することはできない
useStateで更新した処理の後にその値を使って何かしたい場合、処理によっては更新されていない値が取得されてしまいます。
1 2 3 4 5 6 7 8 9 10 11 12 |
const [count, setCount] = useState(0); const increment = () => { setCount(count + 1); console.log(count); // この時点では更新されていないcountの値が出力される }; return ( <div className="App"> <p>Count: {count}</p> <button onClick={increment}>Increment</button> </div> ); |
これを回避するには更新後の値を別の変数で持つようにしましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const [count, setCount] = useState(0); const increment = () => { const nextCount = count + 1; setCount(nextCount); console.log(nextCount); }; return ( <div className="App"> <p>Count: {count}</p> <button onClick={increment}>Increment</button> </div> ); |
useEffect
useEffectは、関数コンポーネント内で副作用を処理するためのHookです。
副作用とは、DOMの操作、APIの呼び出し、タイマーの設定などです。
useEffectは、第1引数に副作用を処理する関数、第2引数に副作用を実行するタイミングを指定する依存配列を取ります。
第2引数が更新されるたびに第1引数の関数が実行されます。
第2引数が空配列の場合、初回レンダリング時のみ第1引数の関数が実行されます。
以下のサンプルでは、ランダムな名言をAPIで取得してそれを表示する例を示しています。
useEffectを使用する際の注意点は無限ループに陥らないようにすることです。以下のように第2引数に渡した値を関数内で更新する処理では無限ループになってしまいます。
1 2 3 4 5 6 7 8 9 10 11 |
const [count, setCount] = useState(0); useEffect(() => { setCount(count + 1); // 依存する値を指定することで無限ループを回避できる }, [count]); return ( <div> <p>Count: {count}</p> </div> ); |
useContext
useContextはコンポーネントのツリー内でデータを共有するために使用されます。
このフックを使用することでコンポーネントのプロパティにデータを渡すことなくコンポーネント間でデータを共有することができます。
要は状態のバケツリレーをする必要がなくなるということです。
以下の例ではuseContextを使って、親コンポーネントからデータを受け取らずに子コンポーネントに渡すことができるサンプルです。
テーマを切り替えるボタンが表示され、押すとテーマが変更されます。
具体的には以下の機能を作る際にはuseContextを使った方が良いでしょう。
- ログイン状態の共有
- 言語設定の共有
- テーマ設定の共有
まとめ
- コンポーネントの状態を管理したい場合はuseState
- APIを呼び出したい場合などはuseEffect
- コンポーネントツリー内でデータを共有したい場合はuseEffect
その2へ続く