useStateについての注意点とHooksについて
なんで useState を使うのか?
下のコードは index の値によって表示する配列を変更する意図で作られたコンポーネントです。
Next のボタンを押すと、イベントハンドラ handleClick が index+1 が実行します。予想では画像が切り替わるはずですが、ページの変化はないです。
以下の理由で画面の画像が変化ないです。
- ローカル変数は、レンダリング間で保持されません。React がこのコンポーネントを 2 回目にレンダリングするときは、最初からコンポーネントレンダリングします。ローカル変数への変更は考慮されません。
- ローカル変数を変更しても、レンダリングはトリガーされません。React は、新しいデータでコンポーネントを再度レンダリングする必要があることを認識していません。
ここでページの表示を変更したいときの要望が二つ出てきます。
- レンダリング間でデータを保持します。
- イベントをトリガーにして、新しいデータでコンポーネントをレンダリングします (再レンダリング)。
ここで登場するのが、useState
です。
useState
は上の二つの要求を満たすために作成されました。
useState の詳しい機能については、割愛します。使い方はそんなに難しくないので、調べてみてください。
上のローカル関数も useState を使って状態を管理すれば、思い通りの用途でページの表示ができます。
Hooks について
React では useState や「use」で始まる他の関数は、フック(Hooks)と呼ばれます。
フックは、 React のレンダリング中にのみ使用できる特別な機能で、React のさまざまな機能に「接続」できます。
useState の状態管理はそれらの機能の 1 つにすぎません
レンダリングに関係するので、Hooks はコンポーネントの一番上の階層でしか使用できません。
条件、ループ、またはその他のネストされた関数内でフックを呼び出すことはできません
。フックは関数ですが、コンポーネントのニーズに関する無条件の宣言と考えると便利です。
ファイルの先頭でモジュールを「インポート」するのと同じように、コンポーネントの先頭で React 機能を「使用」します。
状態は各コンポーネントで完全にプライベートです
状態は、画面上のコンポーネント インスタンスに対してローカルです。
つまり、同じコンポーネントを 2 回レンダリングすると、各コピーは完全に分離された状態になります。
どちらかを変更しても、もう一方には影響しません。
状態はそれを宣言するコンポーネントに対して完全にプライベートです。
親コンポーネントはそれを変更できません。
これにより、残りのコンポーネントに影響を与えることなく、任意のコンポーネントに状態を追加したり削除したりできます。
子コンポーネントの状態を共通化させたいときは、状態を宣言する場所を親コンポーネントに変更しましょう。
useState の状態の管理はどうやっておこなっているのか
useState は、それが参照する状態変数に関する情報を受け取りません。
useState に渡される「識別子」はありません。
内部的には、React は各コンポーネントの状態ペアの配列を保持しています。
また、レンダリング前に 0 に設定されている現在のペア インデックスも維持します。
useState を呼び出すたびに、React は次の状態ペアを提供し、インデックスをインクリメントします。
FYI
Discussion