Open5
React-コンポーネントが再レンダリングされるタイミング
はじめに
Reactでコンポーネントが再レンダリングされるタイミングは大きく分けて2つあります。
- コンポーネント内のStateが変わった時
- 親コンポーネントが再レンダリングされた時
それぞれを簡単にまとめていきたいと思います。
コード紹介
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>
);
}
タイミング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)が変更された時、このコンポーネント全体が再レンダリングされます。
タイミング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も再レンダリングされることになります。
まとめ
Reactにおいてコンポーネントが再レンダリングされるタイミング:
- コンポーネント内のStateが変わった時
- 親コンポーネントが再レンダリングされた時