ReactのuseStateを徹底的に理解する

ReactのuseStateを理解する

Reactを学び始めてからSPA(シングルページアプリケーション)の良さが理解できたところでState Management(状態管理)を学んでいる方、useStateが理解できない方、このコンセプトを理解することは、コンポーネントのレンダーにもかかわる重要な部分になります。 Reduxなどのライブラリを使う前にも理解しておきたいです。 State Management State Managementはデータを管理するフロントエンド側のデータ倉庫のようなものです。これらはReact Hookの機能のうちのひとつです。React Hook(フック)はコンポーネントがマウント(読み込み)されたときにフック(実装)される機能と考えてください。 では実際にReactアプリを作成してコードを書きながらStateManagementを理解していきましょう。Reactのプロジェクトの作成の仕方はこちらの記事を読んでください。 まずは、メインのコンポーネントになるsrc/App.jsxの中身を削除して下記のように記述しましょう。 useState()はreactのデフォルトで使えるStateManagementのメソッドになります。これをインポートして App()のコンポーネント内に定義しましょう。const [count, setCount] でuseStateメソッドの最初の値(データになる部分)をcountという名称にしました。 2番目の値useState[1]にあたる部分は、とsetCountという変数名にしました。慣習として2つ目に来るsetterはsetで始まる名称を付けることが通常になります。setterというのはstate(状態)が変わることを指示をする関数になります。 これで<div>内の{count}の部分がデフォルトの10として表示されます。 ではこの10に1の数字を足す関数を作ってみましょう。 まずは悪い例を紹介します。 ※これは悪い例です。 このボタンをクリックすると、addOne関数が発火されますが何も起きません。。。コンソールを見てみると下記の様なエラーが出ました。 constは再代入できない変数なのでエラーが出ました。 ではこのconst [count, setCount] = useState(10);をletに変えるとどうなるでしょうか? 。。。。。。 。。。。 何も起きません。 しかもエラーも出ません。 なぜでしょうか。 にletを使って変数の値が変えられたとしてもReact側では、state(状態)が変化されたことが察知されていないからです。 ReactのState Managementの推奨ルールとして、constを使う事が定義されています。それは、Reactがコンポーネントを再レンダーした際に新しい値をconstの変数に読み込むことになるからです。それ以外の時に変数が変わってしまってもReactは理解することができません。ですのでその問題を防ぐためにもconstを使うことをお勧めします。 状態の変化を理解する では状態の変化を理解するために、同じ問題を別のコードで再現してみます。 オリジナルのnewNumはそのまま32と表示されますが、上書きした方のmyNumは0に変更されたものが表示されました。 オブジェクトの場合 オブジェクトを上書きした場合は、元のオブジェクトまで変更されてしまいました。 これは、JavaScriptの特徴でプリミティブのデータ(String、Number、Booleanなど)の場合はデータのコピーを返し、Array(配列)やオブジェクトの場合はReference(参照)できるデータを返します。つまり、オリジナルのデータという事になります。 このコンセプトを理解することが重要になります。 ではすべてオブジェクトにしてしまえばよいのでは? そう思って、下記の様にオブジェクトにしたところ、Reactがcountの状態が変わったことを察知できなかったので実際にデータが変わったとしてもRe-render(画面の更新)が行われませんでした。 このようにコンソールには正しくcountの値が更新されていますが、Reactではレンダーされません。 そういう事なので、useState()のsetterを使ってuseState()で設定した値を更新すること必須であることが分かりました。 これは、useStateのsetterを使わないとReactがState Managementで管理しているデータの変化を察知できず、コンポーネントの再レンダーができないからです。 Setterを使ってstateを更新する では今までに学習したことをもとに、useStateについてくるSetter(useStateの2番目にあるメソッド)を使ってcountを更新します。 これでボタンを押したときに関数が変わり、Reactが最新の状態に合わせてレンダー(読み込み)してくれました。 prevStateを使った状態管理で解決できること 前回までに記載した現在の状態を操作するsetCount(count + … Read more