Reactは、ユーザーインターフェースを構築するためのライブラリであり、その中心的な概念には「状態(State)」と「イベントハンドラー(Event Handlers)」が含まれます。これらの概念は、アプリケーションのインタラクティブな動作を制御するために不可欠です。この完全かつ包括的な記事では、Reactの「コンポーネントの状態(Component State)」と「イベントハンドラー(Event Handlers)」について詳しく解説します。
1. コンポーネントの状態(Component State)
Reactにおける「状態(State)」は、コンポーネントの内部で管理されるデータです。このデータは、コンポーネントの描画(レンダリング)に影響を与え、ユーザーインターフェースの動的な変更を可能にします。状態が変更されると、Reactは再レンダリングを行い、画面に反映させます。

1.1 状態の基本的な使い方
Reactのコンポーネントには、状態を保持するためにuseState
フックを使用します。以下に、簡単な例を示します。
javascriptimport React, { useState } from 'react';
function Counter() {
// useStateフックを使って状態を管理
const [count, setCount] = useState(0);
return (
<div>
<p>カウント: {count}p>
<button onClick={() => setCount(count + 1)}>カウントを増やすbutton>
div>
);
}
上記のコードでは、useState(0)
によってcount
という状態を定義し、初期値として0
を設定しています。ボタンがクリックされるたびにsetCount
関数が呼び出され、count
の値が更新されます。この更新が行われると、Reactは自動的に再レンダリングを行い、最新のcount
値を表示します。
1.2 複数の状態を管理する
useState
を複数回呼び出すことで、1つのコンポーネントで複数の状態を管理できます。
javascriptfunction MultiState() {
const [count, setCount] = useState(0);
const [name, setName] = useState("React");
return (
<div>
<p>カウント: {count}p>
<button onClick={() => setCount(count + 1)}>カウントを増やすbutton>
<p>名前: {name}p>
<button onClick={() => setName("React.js")}>名前を変更するbutton>
div>
);
}
このように、複数のuseState
フックを使うことで、それぞれの状態を独立して管理できます。
1.3 状態の更新
Reactの状態は「不変(immutable)」であるため、状態を直接変更することはできません。setState
(またはsetCount
など)を使って状態を更新する必要があります。状態が変更されると、コンポーネントは再レンダリングされ、UIが更新されます。
javascript// 不正な状態更新
count = count + 1; // これはNG
正しい状態更新の方法は次の通りです。
javascriptsetCount(count + 1); // 正しい方法
1.4 関数型の状態更新
状態更新関数は、現在の状態を引数として受け取り、新しい状態を返す関数を受け取ることもできます。この方法は、状態の更新が前回の状態に依存している場合に便利です。
javascriptsetCount(prevCount => prevCount + 1);
このように、prevCount
を使って最新の状態に基づいた更新を行うことができます。
2. イベントハンドラー(Event Handlers)
Reactにおける「イベントハンドラー」は、ユーザーがUIとインタラクションする際に呼び出される関数です。これには、クリックや入力などのイベントが含まれます。イベントハンドラーを使うことで、ユーザーのアクションに対してアプリケーションの状態を更新したり、別の動作をトリガーすることができます。
2.1 イベントの基本的な使い方
Reactでは、イベントハンドラーはキャメルケース(camelCase)で指定します。例えば、クリックイベントはonClick
、キーボードのキー入力イベントはonKeyDown
です。
javascriptimport React, { useState } from 'react';
function ButtonClick() {
const [clicked, setClicked] = useState(false);
const handleClick = () => {
setClicked(!clicked);
};
return (
<div>
<button onClick={handleClick}>クリックbutton>
{clicked && <p>ボタンがクリックされました!p>}
div>
);
}
上記の例では、handleClick
関数がonClick
イベントにバインドされており、ボタンがクリックされると状態clicked
が更新され、メッセージが表示されます。
2.2 イベントオブジェクト
Reactのイベントハンドラーでは、イベントが発生した際にイベントオブジェクトが渡されます。例えば、クリックイベントやキーボードイベントでは、イベントオブジェクトを利用して詳細情報を取得することができます。
javascriptfunction handleClick(event) {
console.log(event.target); // クリックされた要素を出力
}
Reactでは、ブラウザのネイティブイベントとは異なり、合成イベント(SyntheticEvent)というラッパーを使用しています。この合成イベントは、ブラウザに依存せず、統一的なインターフェースを提供します。
2.3 イベントハンドラーでの状態更新
イベントハンドラー内で状態を更新する際には、useState
フックの更新関数を使用します。前述の例でも説明したように、イベントが発生すると、setState
(またはsetCount
)を使って状態を更新し、再レンダリングが行われます。
javascriptfunction handleClick() {
setCount(count + 1); // 状態を更新
}
2.4 イベントハンドラーのバインディング
クラスコンポーネントでは、イベントハンドラーをクラスのインスタンスにバインドする必要があります。しかし、関数コンポーネントでは、useState
やuseEffect
といったフックを利用するため、バインディングは不要です。関数コンポーネントの中で直接イベントハンドラーを定義できます。
javascriptclass CounterClass extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
this.handleClick = this.handleClick.bind(this); // バインディングが必要
}
handleClick() {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<div>
<button onClick={this.handleClick}>クリックbutton>
<p>カウント: {this.state.count}p>
div>
);
}
}
3. 状態とイベントハンドラーを組み合わせた例
状態とイベントハンドラーを組み合わせることで、インタラクティブなアプリケーションを作成できます。以下は、カウントを増やし、減らすボタンを持つコンポーネントの例です。
javascriptfunction Counter() {
const [count, setCount] = useState(0);
const increase = () => setCount(count + 1);
const decrease = () => setCount(count - 1);
return (
<div>
<button onClick={increase}>増やすbutton>
<button onClick={decrease}>減らすbutton>
<p>カウント: {count}p>
div>
);
}
この例では、increase
関数とdecrease
関数をイベントハンドラーとして設定し、それぞれのボタンにonClick
イベントをバインドしています。ボタンがクリックされると、setCount
を呼び出して状態が更新され、再レンダリングが行われます。
4. 結論
Reactにおける「コンポーネントの状態(State)」と「イベントハンドラー(Event Handlers)」は、アプリケーションのインタラクティブな要素を実現するために重要な役割を果たします。状態はコンポーネント内部で管理され、イベントハンドラーはユーザーのアクションに応じて状態を更新します。これらをうまく活用することで、Reactアプリケーションは動的かつ反応的なインターフェースを提供できます。