レンダリングとは??
コンポーネントからDOMノードを作成するための情報の読み込みを行うこと。
レンダリングはDOMに反映させて、画面を描写することではない。
画面に反映させることをレンダリングと思っていたんですが、認識が違ったんですね...
レンダリングされるタイミング
Reactではstate
の値が更新されたときにレンダリングが発生する。
(更新関数が呼ばれ、元々持っていた変数と全く別のものだった場合)
Reactでのstate比較方法
ReactではObject.is
による比較アルゴリズムによって
▷true(stateが同じ)ならレンダリングを行わない
▷false(stateが異なる)ならレンダリングを行う
コードで確認
ボタンをクリックした際にレンダリングが発生するのか確認を行う
1. 数値、文字列の比較
☆レンダリングされない場合
const RenderCheck = () => {
console.log("レンダリング?");
const [check, setCheck] = useState(0);
return (
<>
<button
onClick={() => {
setCheck(0);
}}
>
ボタン
</button>
{check}
</>
);
};
useStateで初期値:0がセットされている。
ボタンのonClick処理で初期値と同じく0をセットすると、レンダリングは行われない(1回目のレンダリングは行われる)
コンソール↓
文字列でも同じ
const [check, setCheck] = useState('abc');
--------------------------------------------
setCheck('abc');
☆レンダリングされる場合
stateが更新用関数によって変更され、中身が異なっている場合
const [check, setCheck] = useState('abc');
------------------------------------------
setCheck(0);
stateの値が変わったことによりレンダリングが発生した
2. オブジェクトの比較
オブジェクトの場合、数値や文字列と同じように見た目上では同じ場合でもレンダリングは発生する
例えば、以下の下の二つのオブジェクトは見た目上では同じ
const object1 = {number:0};
const object2 = {number:0};
これをObject.isで確認する
console.log(Object.is(object1, object2));//false
結果としてfalse
になり別物だということが分かる
先ほどのボタンのプログラムに組み込んでみると
const RenderCheck = () => {
console.log("レンダリング?");
const object1 = {number:0};
const object2 = {number:0};
const [check, setCheck] = useState(object1);
// console.log(Object.is(object1, object2));
return (
<>
<button
onClick={() => {
setCheck(object2);
}}
>
ボタン
</button>
{check.value}
</>
);
};
ボタンをクリックするたびにレンダリングが発生した
▷object2にobject1を渡してあげた場合はレンダリングが発生しない
const object1 = {number:0};
const object2 = object1;
3/. コールバック関数の場合
const RenderCheck = () => {
console.log("レンダリング?");
return (
<>
<button
onClick={(state) => {
return state;
}}
>
ボタン
</button>
</>
);
};
stateをリターンしているだけなので当然レンダリングは発生しない
☆再レンダリングさせるには?
スプレッド演算子を用いて、新しいオブジェクトを作成する
<button
onClick={(state) => {
const newState = {...state};
return newState;
}}
>
ボタン
</button>
newState
はstate
を展開した新しいオブジェクトになっているので、レンダリングが発生する条件と一致する。
オブジェクトの値の渡し方などの詳しいことは↓
参照:https://qiita.com/yuta0801/items/f8690a6e129c594de5fb