👀

ポケモンで学ぶPropsとState

2023/12/28に公開

React の Props(プロップス)と State(ステート)は、React でウェブアプリケーションを作る時に大切な概念です。
ポケモンのゲームを例に説明していきます。

Props(プロップス)

Props は、React のコンポーネントに渡されるデータです。
これは親コンポーネントから子コンポーネントへと渡されます。
Props は読み取り専用で、コンポーネント内で変更することはできません。

ポケモンのゲームで考えると、あるポケモントレーナー(親コンポーネント)が自分のポケモン(子コンポーネント)に指示(Props)を出すようなものです。
トレーナーはポケモンに「たたかう」や「にげる」といった指示を出しますが、ポケモン自身がこの指示を変えることはできません。

State(ステート)

State は、コンポーネント内で管理されるデータです。
これはコンポーネント内で変更することができ、変更されるとコンポーネントは再レンダリングされます。

ポケモンのゲームで考えると、ポケモン自身の体力や状態異常などが State にあたります。
バトル中にポケモンがダメージをうけると体力(State)が減りこれによって、表示される体力バーが変化します。

実際のコード例

ここでは、React を使って簡単なポケモン関連のコンポーネントを作成してみます。

jsx
import React, { useState } from 'react';

// ポケモンコンポーネント
const Pokemon = ({ name, initialHp }) => { //propsの名前は一般的にキャメルケース(camelCase)記法
  const [hp, setHp] = useState(initialHp); // State: 体力

  // 体力を減少させる関数
  const takeDamage = () => {
    setHp(hp - 10);
  };

  return (
    <div>
      <h2>{name}</h2>
      <p>体力: {hp}</p>
      <button onClick={takeDamage}>ダメージを受ける</button>
    </div>
  );
}

// トレーナーコンポーネント
const Trainer = () => {
  return (
    <div>
      <h1>ポケモントレーナー</h1>
      <Pokemon name="ピカチュウ" initialHp={100} /> {/* Propsを渡す */}
    </div>
  );
}

export default Trainer;

このコードでは、Trainer コンポーネント(親)が Pokemon コンポーネント(子)に名前(name)と初期体力(initialHp)という Props を渡しています。
ポケモンコンポーネントは、自分の体力(hp)を State として持ち、ダメージを受けるたびにこれを更新します。
実際に、以下のような動きになります。

補足

コンポーネントの更新タイミング

コンポーネントで再描画がおこなわれるのは主に以下のタイミングです。

  • Stateが更新された場合
  • 渡されたPropsが変更された場合
  • 親コンポーネントが再描画された場合

Props と引数の違い

Props は React コンポーネントで使われる特別な種類の「引数」のようなものです。
しかし、Props はその性質と使用法において、一般的な関数の引数とは異なる特徴を持っています。

useState

const [hp, setHp] = useState(initialHp)というコードは、React のフック(Hook)であるuseStateを使用しています。
この構造では、コンポーネントの「状態」を管理するために使われます。

役割

useStateは、コンポーネント内で状態(State)を作成・管理するためのフックです。
状態とは、コンポーネントのデータや情報のことで、このデータが変わるとコンポーネントは再レンダリングされます。

構文と構造

  • useState(initialHp)の呼び出し
    ここでは、useStateを呼び出し、初期値のinitialHpを渡しています。
    initialHpはこの状態の初期値です。
    例えば、ポケモンの初期体力を 100 に設定したい場合はinitialHpに 100 を渡します。

  • 配列分割代入:const [hp,setHp] = useState(initialHp)
    上記の部分で行われているのは、配列分割代入です。
    useStateは 2 つの要素を持つ配列を返します。
    1 つ目の要素は現在の状態(この例では、hp)、2 つ目の要素はその状態を更新するための関数(この例では、setHp)です。

動作の流れ

  • 1.初期化
    コンポーネントが最初にレンダリングされるとき、useStateに渡された値(initialHp)がhpの初期値として設定されます。
  • 2.状態の読み取り
    コンポーネント内で、hpを使うと、現在の体力の値が得られます。
  • 3.状態の更新
    setHp関数で呼び出すことで、hpの値を更新できます。
    例えばsetUp(hp - 10)を実行すると、現在のhpから 10 減った値が新しいhpになります。
  • 4.再レンダリング
    hpが更新されると、コンポーネントは自動的に再レンダリングされ、最新のhpの値が画面に表示されます。

アロー関数

const takeDamage = () => { setHp(hp - 10); }; という記述はアロー関数(Arrow Function)を使用したものです。

アロー関数の基本

アロー関数は以下のような構文で記述されます。

javascript
const functionName = (引数) => {
    //関数の本体
}

この場合、takeDamageは関数名で、アロー(=>)の左側には引数がきます。
今回の場合は、引数はありません。
アローの右側には関数の本体が記述されます。

アロー関数と const の組み合わせ

アロー関数は、constと組み合わせてよく使われます。
これにより、変数に関数式を割り当てることができます。
この方法で定義された関数は、「匿名関数」として知られています。

Discussion