環境
MacBook Pro (2.3 GHz 8コアIntel Core i9)
macOS 14.0(23A344)
Homebrew 4.3.8
gh 2.52.0
まとめ
デフォルトの動作では、副作用関数はレンダーの完了時に毎回実行されます。
新しい購読を設定する必要があるのは毎回の更新ごとではなく、source プロパティが変化した場合のみです。
useEffect の第 2 引数として、この副作用が依存している値の配列を渡します。
つまり、useEffectの依存配列(第二引数)を活用することで、StateやPropsが変更された場合にどの副作用(関数)を実行するかを細かく制御できます。
基本構文
StateまたはPropsとして、countを設定した場合、console.log("countが変更されたときに実行")が副作用として実行される
e.g.
useEffect(() => {
console.log("countが変更されたときに実行");
}, [count]); // countが変更されたときのみ実行
活用例
フォルダ構成
folda_structure
├── public/
│ ├── index.html
└── src/
│ ├── index.js(index.jsx)
│ └── App.js(App.jsx)
index.html
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
index.js
index.js
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { App } from "./App";
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
App.js(useEffectなし)
- 課題:on/off
buttonを使って、\(^o^)/オワタの表示・非表示が制御できない - 考察:レンダリングの度に、
if文に入るため、onClickToggleの制御が上書きされる
App.jsx
import { useState } from "react";
export const App = () => {
const [num, setNum] = useState(0);
const onClickCountUp = () => {
setNum(num + 1);
};
const [isShowFace, setIsShowFace] = useState(false);
const onClickToggle = () => {
setIsShowFace(!isShowFace);
};
if (num > 0) {
if (num % 3 === 0) {
isShowFace || setIsShowFace(true);
} else {
isShowFace && setIsShowFace(false);
}
}
return (
<>
<button onclick={onClickCountUp}>カウントアップ</button>
<p>{num}</p>
<button onclick={onClickToggle}>on/off</button>
{isShowFace && <p>\(^o^)/オワタ</p>}
</>
);
};
App.js(useEffectあり)
- 対策:
useEffectを使用して、numが更新された時のみif文が作動するように設定 - 結果:on/off
buttonを使って、\(^o^)/オワタの表示・非表示が制御できる
App.jsx
import { useEffect, useState } from "react";
export const App = () => {
const [num, setNum] = useState(0);
const onClickCountUp = () => {
setNum(num + 1);
};
const [isShowFace, setIsShowFace] = useState(false);
const onClickToggle = () => {
setIsShowFace(!isShowFace);
};
+ useEffect(() => {
if (num > 0) {
if (num % 3 === 0) {
isShowFace || setIsShowFace(true);
} else {
isShowFace && setIsShowFace(false);
}
}
+ }, [num]);
return (
<>
<button onclick={onClickCountUp}>カウントアップ</button>
<p>{num}</p>
<button onclick={onClickToggle}>on/off</button>
{isShowFace && <p>\(^o^)/オワタ</p>}
</>
);
};
処理の流れ
カウントアップbuttonの操作(useEffectHook内)
-
num + 1で、引数numを1つずつ増やす -
useState(true)で、isShowFaceの初期値をfalseに設定する -
||で、引数(state)isShowFaceがfalseの時にsetIsShowFace(true)でisShowFaceをtrueにする -
&&で、引数(state)isShowFaceがtrueの時にsetIsShowFace(false)でisShowFaceをfalseにする -
&&で、引数(state)isShowFaceがtrueの時に\(^o^)/オワタが表示される
on/offbuttonの操作(useEffectHook外)
-
!isShowFaceで、引数isShowFaceを反転させる -
&&で、引数isShowFaceがtrueの時に\(^o^)/オワタが表示される
