Effect Hook とは
レンダリング後の DOM の変更や、状態の更新、他コンポーネントに対して影響を及ぼす処理(effects)を制御するための Hooks API になります。
基本的な書き方は下記、 useState と同様に import して関数コンポーネント内に記述することです。
import React, { useEffect } from "react"
// 関数コンポーネント内で下記を記述する
useEffect(() => {
// 処理をここに書く
// 【option】関数を返すようにすると、アンマウントされる前に関数が実行される。
return () => console.log('クリーンアップを実行');
}, []);
Effect Hook は以下のタイミングで実行される。
- レンダリング後に必ず実行する。
- 初回のレンダリング後だけ実行する。
- 指定したデータに変更があった場合のみ実行する。
- 例で示した文の
[]
のところに、何の変更をトリガーにするかを書くことができる。
- 例で示した文の
利点として、State など、Reactの機能をEffect Hookの関数内で利用できること。
Effect の利用ケース
- APIとの通信
- State を設定して、レンダリング後に API からデータを取得してセットする。
- Stateを変更させたときに、他に影響を与える場合
- 例えばチャットアプリで相手から返信が来た時に、タイトルに未読件数を表記するとか
サンプル
State の変更を受け取って、ページのタイトルを変更する Effect Hook を実装します。
記事投稿サイトみたいなのをイメージしてます。
App.tsx
import React, { useState, useCallback, useEffect } from "react";
import { InputForm } from "./InputForm";
import "./styles.css";
export default function App() {
const [content, setContent] = useState<string>("test");
const onChangeContent = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setContent(event.target.value);
},
[]
);
useEffect(() => {
document.title = `${content} が入力されている。`;
console.log("content が変更された");
}, [content]);
return (
<div className="App">
<InputForm content={content} onChange={onChangeContent} />
<div>
<span>content の値は、"{content}"</span>
</div>
</div>
);
}
InputForm.tsx
import React from "react"
interface Props {
content: string;
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
}
export const InputForm = (props: Props) => {
return <input defaultValue={props.content} onChange={props.onChange}></input>
}
簡単ではありますが、codesandboxにサンプルのコードを上げてます。
余分な関数の実行や、知らぬ間に DOM が書き換わってしまっている、を防ぐために、第二引数はなるべく入れとく方が良いのかなと思ったりしました。
その他
- useEffect は1つのコンポーネント内で複数設定が可能
- 異なる変数を第二引数に設定するなどもできる