ReactのuseStateは、stateとその更新関数をペアにして返すフックと呼ばれる状態を管理するためのものです。
それは関数コンポーネント内でstateを持つことを可能にします。
基本的な使い方と応用的な使い方、注意点をコードを交えて解説したいと思います。
使い方
import React, { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
- useStateをimportします。
useState
フックを使用してcount
という新しいstate変数を宣言。こ- useStateの引数に指定した値が初期値になりcountに格納されます。上記のコードでいうと数値の0が初期値として扱われます。
setCount
はcount
変数を更新する関数となっています。- ボタンをクリックするたびに、onClickというクリックイベントが発火され
setCount
関数が呼び出され、count
の値が更新する
応用的なテクニック
useStateの応用的なテクニックをいくつか紹介します。
前の状態に基づいて次の状態を設定する
前の状態を基に次の状態を設定することができます。これは、カウンターのような状態が前回の更新に依存する場合に特に有用です。例えば、カウンターをインクリメントするには以下のようにします
setCount(prevCount => prevCount + 1);
または、より短い構文を使用することもできます
setCount(prevCount => ++prevCount);
これらの構文は、prevCountの値をインクリメント(加算)してから新しい値を設定します。
オブジェクトの状態を更新する
状態としてオブジェクトを格納することも可能です。オブジェクトの一部のプロパティだけを更新したい場合は、スプレッド演算子を使用すると便利です。例えば、以下のようにuserInfoというオブジェクトの状態を更新することができます
const [userInfo, setUserInfo] = useState({name: 'John', age: 20});
// nameだけを更新
setUserInfo(prevUserInfo => ({...prevUserInfo, name: 'Mike'}));
この場合、prevUserInfo
は以前のuserInfo
の状態を参照します。{...prevUserInfo, name: 'Mike'}
とすることで、prevUserInfo
のプロパティを全てコピーし、その上でname
の値だけを'Mike'
に更新します。この時、オブジェクトを囲っている波括弧の外側に丸括弧があるのは、JavaScriptの構文上の問題を回避するためです。JavaScriptでは、波括弧を直接使うと、それがブロックと解釈されてしまう可能性があります。そのため、オブジェクトリテラルを直接返す場合は、丸括弧で囲んで、それが式であることを明示します。
このテクニックを使用することで、一部のプロパティだけを効率的に更新することができます。
prevUserInfoというのは内部的に以前の以前のuserInfoの状態を参照してますが、命名規則は固定ではありません。
これらは開発者が任意で設定する名前で、関数内部でのみ有効な仮引数です。開発者は理解しやすく、コードの意図を明確に示す名前を選ぶべきです。重要なのは、この引数が以前の状態を参照するということを理解することです。以下のように、引数の名前は自由に変更できます
setCount(previousCount => previousCount + 1);
setUserInfo(oldUserInfo => ({...oldUserInfo, gender: 'male'}));
この場合でも、previousCountとoldUserInfoは前の状態を参照します。
注意点
直接変更しない
Stateは直接変更しないでください。代わりに、更新関数(この例ではsetCount)を使用してStateを更新します。以下がこの例のコードです
// 正しくない:Stateを直接変更しています
// count = count + 1;
// 正しい:更新関数を使用してStateを更新します
setCount(count + 1);
更新関数は非同期的に動作する可能性があります。
次のStateの値が現在のStateの値に依存する場合には、関数を更新関数に渡すことを推奨します。以下がこの例のコードです
// 非同期的な動作のため、次の行は期待した結果を返さない可能性があります
setCount(count + 1);
console.log(count); // 更新された値を期待していますが、古い値が表示される可能性があります
// 正しい:関数を更新関数に渡します
setCount(prevCount => prevCount + 1);
条件付きに呼び出すことはできない
必ずコンポーネントのトップレベルで記述する必要があるのでif文やfor文の中に記述するのは避けてください。
const Card = () => {
// 正しい:呼び出しは一貫して同じ順序で行われます
const [value, setValue] = useState(0);
// 正しくない:条件付きにuseStateを呼び出しています
if (something) {
const [value, setValue] = useState(0);
}
return(
<>
</>
)
}
まとめ
こちらではuseStateの基本的な使い方や注意点などを説明してきました。React Hooksの中ではよく使われるのと、オブジェクトリテラルや配列などを使ったstateの管理もよくあるケースなのでしっかりと押さえておきましょう。
最後までご覧いただき、ありがとうございます。
ご不明点やご相談、お仕事の依頼はいつでもお気軽にご連絡ください。
コメント