こんにちは!Reiです(˵ •̀ ᴗ – ˵) ✧
Stateを使い始めると、気になってくるのが…
「ボタンを押したら、なんで画面が変わったの?」
「なんでこの処理がもう一回動いたの?」
というところかなって思います!
ここで出てくるのが、
「再レンダリング」と「副作用」という考え方。
この2つ、最初はかなり混ざって見えやすいんですが、順番で整理するとシンプルに理解できます!
Reactが、
「どのタイミングで画面を作り直しているのか」
「どのタイミングで処理が動いているのか」
この流れを見ながら、再レンダリングと副作用について整理していきます!

Reactで開発していく上で重要な観点なので、ぜひ学んで帰ってくださいね!
再レンダリングとは?
まずはここから!
Reactでは、
StateやPropsの値が変わると、コンポーネントをもう一度実行して、新しい値をもとに画面を更新されます。
これが 再レンダリング と呼ばれるものです。
(とっても重要ポイント!)
ボタンを押すと数字が増えるカウンター を例に挙げると、
最初は「0」と表示されていて、
ボタンを1回押すと「1」に変わり、
もう一度押すと「2」になる
このとき、Reactは数字だけを書き換えているわけではなくて、コンポーネントをもう一度実行して、表示を作り直しているんです。
再レンダリングが起きるきっかけ
じゃあ、どんなときに起きるのかというと、
- Stateが変わったとき
- Propsが変わったとき
- 親コンポーネントが再レンダリングされたとき
の3つのタイミングで再レンダリングが起こります!
Stateが変わったとき
Stateは、コンポーネントの中で表示を作るときに使われています。
なのでStateが変わると、
その値を使っている表示の内容も変える必要があります。
そのため、その値をもとにもう一度コンポーネントを実行して、表示を作り直しています。
Propsが変わったとき
Propsは、親コンポーネントから渡される値で、子コンポーネントは、そのPropsをもとに表示を作っています。
そのため、Propsが変わると、
表示に使っているデータの内容が変わることになります。
なのでReactは、
新しいPropsの内容に合わせて、もう一度コンポーネントを実行し直し、表示を更新するのです。
親コンポーネントが再レンダリングされたとき
親コンポーネントが再レンダリングされると、その中にある子コンポーネントも一度実行されます。
これは、親コンポーネントが実行されるときに、その中に書かれている子コンポーネント一緒に処理されるためです。
そのため、子コンポーネント側で何も変更していなくても、親の再レンダリングをきっかけに実行されることがあります。
ただし、毎回必ず再描画されるわけではなく、前回と同じ結果であれば、そのまま使われることもあります 👀
再レンダリングの動きを確認してみる
ちょっとコードで見てみましょう!
import { useState } from "react";
import { Message } from "./Message";
export const App = () => {
console.log("Appのレンダリング");
const [isShow, setIsShow] = useState(true);
const onClickButton = () => {
setIsShow(!isShow);
};
return (
<>
<Message>お元気ですか?</Message>
<button onClick={onClickButton}>表示/非表示</button>
{isShow && <p>元気</p>}
</>
);
};
このコードでは、
1. ボタンを押す
2. isShow が変わる
3. App がもう一度実行される
4. 表示が作り直される
で動いています。
つまり、
Stateが変わる → 再レンダリング → 表示が更新される
という流れで画面が更新されているのです!
レンダリング中にStateを変えるとどうなる
ここ、ちょっと考えてみてください 👀
コンポーネントの実行中にStateを更新したらどうなるでしょうか?
const [num, setNum] = useState(0);
const [isShow, setIsShow] = useState(true);
if (num % 3 === 0) {
setIsShow(true);
}
このコード、パッとみ普通に動きそうなんですが…
実際はこうなるんです↓
1. コンポーネントが実行される
2. 実行中にStateが更新される
3. 再レンダリングが起こる
4. また同じ処理が走る
これ、ずーっと繰り返されてしまうので
無限ループになってしまうんです ( ; ˘-ω-)
なので、レンダリング中にStateを更新するのは避ける 必要があります…!
副作用とは?
ここで、
「じゃあ、値が変わったときに処理を動かしたいときは?」
と疑問が出てくると思います。
このときに出てくるのが「副作用」という考え方。
副作用とは、
StateやPropsの変化をきっかけにして、あとから実行される処理のことです。
たとえばこんなもの↓
・データの取得
・特定の値になったときの処理
・タイトルの変更
こういった処理は、
レンダリングとは別のタイミングで動かす必要があります!
useEffectで副作用を扱う
副作用を書くときに使うのが useEffect です。
useEffect は、
レンダリングが終わったあとに処理を実行してくれる仕組みです。
基本の形はこんな感じ↓
useEffect(() => {
// 実行したい処理
}, [監視する値]);
- 第1引数:実行したい処理(関数)
- 第2引数:どの値が変わったときに実行するか
ここで大事なのは、
「いつこの処理を動かすか」を自分で決められるところです!
依存配列で「いつ動くか」を決める
この [監視する値] は、依存配列と呼ばれます。どの値が変わったときに、この処理を動かすのかを指定します。
たとえば、
[num]→ numが変わったときに実行[isShow]→ isShowが変わったときに実行
といったように、
どの値をきっかけに処理を動かすのかを決めることができます。
ここで大事なのは、
「この処理は、どの値の変化に反応して動くのか?」を指定すること。
依存配列で指定することで、どのタイミングで処理が実行されるのかをコントロールできるようになります。
再レンダリングと副作用は分けて考える
ここが一番大事なポイントです!
Reactで起きていることは、
- 再レンダリング(コンポーネントの再実行)
- 副作用(あとから動く処理)
この2つに分けて考えられます。
この2つが混ざってしまうと、
「どこで画面が変わったのか」「どこで処理が動いたのか」
が分かりにくくなってしまいます 💦
なので、
- まず再レンダリングで画面が更新される
- そのあとに副作用が実行される
という順番で考えるのがポイントです!
今回のポイントおさらい !!
ここまでの内容を整理すると↓
再レンダリング
・StateやPropsの変化でコンポーネントがもう一度実行される
・画面に使っている値が変わると、表示も作り直される
副作用
・値の変化や関数の実行をきっかけにあとから実行される処理
・レンダリングとは別のタイミングで動く
再レンダリングと副作用は、最初は少し混ざって見えやすいですが、「画面を更新する処理」と「あとから動く処理」に分けて考えることで、理解しやすくなるはずです!
最後に
再レンダリングと副作用は、最初は少し少し分かりにくく感じる箇所かなと思います。
ただ、このあたりはReactを使っていく中で何度も出てくる大事な考え方。
最初から完璧に理解しようとしなくても大丈夫なので、開発しながら少しずつ触れながら慣れていければOKです!
この記事が、再レンダリングと副作用を整理するヒントになっていたら嬉しいです ᥫᩣ ̖́-


コメント