Open5

React-コンポーネントが再レンダリングされるタイミング

geDemgeDem

はじめに

Reactでコンポーネントが再レンダリングされるタイミングは大きく分けて2つあります。

  • コンポーネント内のStateが変わった時
  • 親コンポーネントが再レンダリングされた時

それぞれを簡単にまとめていきたいと思います。

geDemgeDem

コード紹介

Reactのチュートリアル(途中ですが)を例に書いていきます。
OXゲームの開発です。(途中)

Squareコンポーネントがクリックされると、その場所にXを入力するといった感じです。

import React, { useState } from "react";

// Squareコンポーネント
// 親(Board)から四角の番号・クリックした時の処理を受け取る
function Square({value, onSquareClick}) {
  return (
    <button className="square" onClick={onSquareClick}>{value}</button>
  );
}

// Boardコンポーネント
export default function Board() {
  // それぞれの四角を一意にするためのリスト生成
  const [squares, setSquares] = useState(Array(9).fill(null));
  // 四角が押された時に、引数として渡された欄にXを記入
  function handleClick(i) {
    const nextSquares = squares.slice();
    nextSquares[i] = "X"
    setSquares(nextSquares)
  }

  return(
    <div className="board">
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      <div className="board-row">
        <Square value={squares[3]} onSquareClick={() => handleClick(3)} />
        <Square value={squares[4]} onSquareClick={() => handleClick(4)} />
        <Square value={squares[5]} onSquareClick={() => handleClick(5)} />
      </div>
      <div className="board-row">
        <Square value={squares[6]} onSquareClick={() => handleClick(6)} />
        <Square value={squares[7]} onSquareClick={() => handleClick(7)} />
        <Square value={squares[8]} onSquareClick={() => handleClick(8)} />
      </div>
    </div>
  );
}

geDemgeDem

タイミング1:コンポーネント内のStateが変わった時

Squareコンポーネントを例に説明します。

先ほどコードを見せたばかりですが、理解しやすさのために、便宜上いい感じのコードに書き換えます。

// Squareコンポーネント
function Square() {

  // 同じ場所がクリックされた数を数える
  const [clickTime, setClickTime] = useState(0);

  // クリック回数を増やす
  function countClickTimes() {
    setClickTime((clickTime) => clickTime + 1);
  };

  return (
    // クリックされた回数を表示
    <button className="square" onClick={countClickTimes}>{clickTime}</button>
  );
}

実行イメージ

クリックされたら、四角に書かれている数字が上がっていくコードに変わりました。



このコードでは、「clickTime」という状態変数(State変数)が宣言されています。
この「clickTime」の状態(State)が変更された時、このコンポーネント全体が再レンダリングされます。

geDemgeDem

タイミング2:親コンポーネントが再レンダリングされた時

コードを元に戻します。

import React, { useState } from "react";

// Squareコンポーネント
// 親(Board)から四角の番号・クリックした時の処理を受け取る
function Square({value, onSquareClick}) {
  return (
    <button className="square" onClick={onSquareClick}>{value}</button>
  );
}

// Boardコンポーネント
export default function Board() {
  // それぞれの四角を一意にするためのリスト生成
  const [squares, setSquares] = useState(Array(9).fill(null));
  // 四角が押された時に、引数として渡された欄にXを記入
  function handleClick(i) {
    const nextSquares = squares.slice();
    nextSquares[i] = "X"
    setSquares(nextSquares)
  }

  return(
    <div className="board">
      <div className="board-row">
        <Square value={squares[0]} onSquareClick={() => handleClick(0)} />
        <Square value={squares[1]} onSquareClick={() => handleClick(1)} />
        <Square value={squares[2]} onSquareClick={() => handleClick(2)} />
      </div>
      ・
      ・
    </div>
  );
}



このコードの構成は、以下のようになっています。

Board
  └ Square

親コンポーネントであるBoardは「squares」という状態変数を持っており、これは、「handleClick」の関数内において、"X"を記入するために状態が変更されます。

なので、「squares」のStateが変わった時、親コンポーネントが再レンダリングされます。

タイミング1で書いたように、コンポーネント内が再レンダリングされるときは、コンポーネント内に書かれた全てが再レンダリングされるため、Board下のSquareも再レンダリングされることになります。

geDemgeDem

まとめ

Reactにおいてコンポーネントが再レンダリングされるタイミング:

  • コンポーネント内のStateが変わった時
  • 親コンポーネントが再レンダリングされた時