React hooks
Overview
React HooksはReact 16.8で追加された新機能であり、stateなどのReact機能をクラスコンポーネントを使用せず使えるようになるもの。
useState
「useStateの値を更新しても反映されない!」の解決方法
setStateで値が更新されるのは関数が呼び出された後。つまり関数内では新規の値にアクセスができず、再レンダリングの際に確認ができる。
useStateは状態と状態を更新する関数を返す useStateのset関数はレンダリング後に更新される。 setterに関数を渡すと引数に最新の値が取得できる。
特徴
- ページをリロードするとstateはリセットされる(初期値になる)
- stateの値はセット関数を使って更新する
- stateが更新されるとコンポーネントは再レンダリングされる
- 再レンダリング後もstateの値は保持され、最新のstateの値を関数に渡す
関数が状態を持てるようになる。
一番トップのコンポーネントでuseStateを宣言して子コンポーネントで共有する。
関数の定義は決まった処理を返すというものを理解しておくこと。
それに状態をもたせるようにした。
useEffect
useEffect が API 呼び出しを行うのに適していない理由
関数内のある状態に着目して処理をほどこす。
useEffect無限ループについて
関数型の React コンポーネントにおいて、内部状態またはプロパティが変更されると、コンポーネントの関数が再実行されるからです。 関数型の React コンポーネントにおいて、関数の結果が前回の呼び出し時と異なれば、レンダリングが発生するからです。
useRef
関数コンポーネントでは、Classコンポーネント時のref属性の代わりにuseRefを使って要素への参照をする。
※useRefではuseStateのようにコンポーネント内での値を保持できる。
- DOMの参照例
const App = () => {
const inputEl = useRef(null);
const handleClick = () => {
inputEl.current.focus();
console.log("inputEl.current:", inputEl.current);
// console.log → inputEl.current: <input type="text">
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={handleClick}>入力エリアをフォーカスする</button>
</>
);
};
useStateとuseRefの違い
コンポーネントの再レンダリングはしたくないけど、内部に保持している値だけを更新したい場合は、保持したい値をuseStateではなく、useRefを利用するのが良い 。
useReducer
配列やオブジェクトの一部を操作する場合のように前回の状態に依存した更新処理をする場合にはuseStateの代わりにuseReducerを利用することでより簡潔に記述することができる。
状態管理のためのhookでuseStateと似たような機能。useStateはuseReducerに内部実装されている。
const [state, dispatch] = useReducer(reducer, initialState);
dispatchを実行すればレンダリングが走る。
- 使用例 たとえば、レンダリングが走らないな。とか思ったときに強制的にレンダリングをかけたい場合
const [_, dispatch] = useReducer((boolean) => !boolean, false);
あとはdispatchを特定の場所で実行すればレンダリングがかかる。
useContext
React Context APIわかりやすい
useContextでundefinedを抜く
※コンポーネントの再利用をより難しくするため慎重に利用しなくてはならない。
useContextとは、Context機能をよりシンプルに使えるようになった機能(JSのContextのスタックの概念)
useContext() + Contextオブジェクト + Providerコンポーネント
これがuseContextの正体。
Context APIについて
Context APIとは、Contextオブジェクトとそれに備わったProviderとConsumer 、この3つを提供するもの。
フックのひとつであるuseContext()はこの Consumer
の代わりになるものです。
Consumerをそのまま使うと複雑になりがちな処理が useContext()
を使うとシンプルに書ける。
useContext重要なこと
useContextを呼び出すコンポーネントはコンテキストの値が変化するたびに毎回再レンダーされる。