前回の記事で解説したpropsと並び、React.jsを使う上で必須となる知識として、stateがあります。
propsよりも難易度が高いので、サンプルプログラムを多めに使いつつ、まずは基本的な内容についてじっくりと解説していきます。
目次
stateとは
React.jsのstateとは、Reactコンポーネントの「状態」のことです。英単語の意味通りですね。
実用的なアプリを開発しようとすれば、ユーザーの操作によって生じる状態の変化をブラウザ画面に反映させる機能が欲しくなります。
その際、コンポーネント(部品)の現在の状態(state)を記憶しておくために使われるメモリをstateといいます。
コンポーネントにstateを追加するuseState
Reactコンポーネントにstateを追加するには、useStateという関数を使います。
useStateは、2019年2月6日リリースのReact v16.8で導入された「Reactフック」のひとつです。
React.jsには、useStateの他にも「use」から始まる「Reactフック」がいくつかあります。
下準備
サンプルプログラムには、前回までで作成済のhello-appプロジェクトを使用しますので、まだプロジェクトを作成していない方は、こちらの記事を参考に作成してください。
プロジェクトが作成できたら、main.jsxファイルを以下のように編集しておきます。
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'
createRoot(document.getElementById('root')).render(
<StrictMode>
<App /> // 👈このAppが今回作成するコンポーネント
</StrictMode>,
)
次に、App.jsxを開き、元々あるコードはすべて消去しておきます。
これで下準備は完了です。
useStateを使用するサンプルプログラム
useStateを使用するには、ReactからuseStateをインポートする必要があります。
App.jsxファイルの先頭に次の1行をプログラムしてください。
import { useState } from 'react'
続いて、コンポーネント関数の枠を作り、他のファイルから使用できるようエクスポートします。
import { useState } from 'react'
function App() {
// この中に処理をプログラムしていく
}
export default App
では、処理を記述していきましょう。
import { useState } from 'react'
function App() {
const [count, setCount] = useState(0) // *1
// *2
const handleClick = () => {
setCount(count + 1)
}
return (
<>
<button onClick={handleClick}>Count Up</button>
<div>{count}</div>
</>
)
}
export default App
*1のコード解説
const [count, setCount] = useState(0)
useState関数を呼び出し、結果を受け取っています。丸カッコ内の引数はstate変数の初期値です。
非常に重要な注意点として、「use」から始まる関数(Reactフック)は、コンポーネントの先頭、またはカスタムフック(※1)内でのみ呼び出し可能です。

※1:カスタムフックとは、自作のフックです。
Reactに元々用意されている組み込みフックではカバーできない処理が欲しい場合などに作成します。
本記事はまだ入門編なので、カスタムフックについて詳しくは触れませんが、いずれ詳しい記事を投稿する予定です。
useState関数からの戻り値は、角カッコ([])を使って記述し、配列の分割代入と呼ばれます。
角カッコ内の1つ目の要素がstate変数、2つ目はstate変数を設定する関数です。
*2のコード解説
const handleClick = () => {
setCount(count + 1)
}
handleClickは、ボタンがクリックされた際に呼び出される関数です。handleClick関数内で、setCount関数を呼び出し、countを1増加させています。
複数のstateを追加する
Reactコンポーネントは複数のstateを持つことができます。
前項までで作成したAppコンポーネントはcountというstateを1つ持っていますが、使い方のヒントテキストの表示/非表示を切り替えるhintVisibleというstateを追加してみます。
表示か非表示かを切り替える二択なので、論理値型(true/false)を使います。
また、表示/非表示のようにOn/Offを切り替えることをトグル(Toggle)と言いますので覚えておきましょう。
以下のように、App.jsxのプログラムを変更してください。
import { useState } from 'react';
function App() {
const [count, setCount] = useState(0)
// 👇この行を追加して2つ目のstateを作成
const [hintVisible, setHintVisible] = useState(false)
const handleClick = () => {
setCount(count + 1)
}
// 👇この関数を追加
const handleToggle = () => {
setHintVisible(!hintVisible)
}
return (
<>
<button onClick={handleClick}>Count Up</button>
<div>{count}</div>
// 👇以下の太字、赤マーカーのコードを追加
<button onClick={handleToggle}>
{hintVisible ? 'ヒント非表示' : 'ヒント表示'}
</button>
{hintVisible && <p>ボタンを押すとカウントアップします。</p>}
</>
)
}
export default App
上記の例のように、個々のstateが独立していて互いに関連していない場合は、状態ごとにstate変数を作成する方法で問題ありません。
今回で言えばカウントの状態を持つcount変数と、表示状態を持つhintVisible変数です。
しかし、一方の状態が変化するともう一方の状態も影響されて変化する場合や、複数の状態を同時に変化させる必要がある場合、複数の状態が相互に影響し合うケースでは、別々のstate変数として作成するよりも、1つのstate変数の中に複数の状態を持たせる方法が望ましいでしょう。
複数の状態を持つstate変数については、本記事では詳しく説明しませんが、例えばオンラインショップであれば、何かの商品をカートに入れる際に「商品名」、「価格」、「個数」などの情報が同時に必要です。
その場合のstateの記述方法を参考のため掲載しておきます。
// 商品名、価格、個数を持つstate
const [cart, setCart] = useState(
{
name: "",
price: 0,
count: 0
}
)
まとめ
stateとは、コンポーネントが状態についての情報を記憶しておくためのメモリである。stateを宣言、初期化するにはuseState関数というReactフックを呼び出す。- useState以外にも「use」から始まるフックが存在する。
- useStateをはじめとする各Reactフックは、コンポーネントの先頭またはカスタムフック内でのみ呼び出し可能である。
- useStateフックは、現在のstateとその
stateを更新する関数の組み合わせを「配列の分割代入」として返す。 - 1つのコンポーネントに複数の
state変数を持つことができる。
本記事についての質問、誤りの指摘、ご意見ご感想などありましたら、ぜひコメント頂ければ幸いです。
それでは、最後までお読みいただき、ありがとうございます。

コメント