useEffectって?
そもそもuseEffectって何?いつ使うの?という疑問があるかと思います。ここでは僕流の考え方で話します。まだまだ浅いですが、内容整理のためのメモを覗いていると思ってください。
useEffectは非同期処理をする際に学びます。※今はuseSWRやNext.jsのSRCなど便利なものが出ていますが、とりあえずここを通りました。
まず、Reactで非同期処理を実装したい場合にasync awaitが使えませんよね。ではどうするか、useEffectの中にasync関数を書きます。形式上はそれで問題ないです。
そもそもなぜuseEffectの中に入れないとダメなのか?それにはuseEffectの中に書いた処理がどのタイミングで実行されるかを見ていきましょう。
useEffectの中に書いた処理がユーザーの画面に表示されるのは、仮想DOMの構築が終わって、実際のDOMへ反映された「後」です。
はい?
仮想DOM?
そうですよね。まずはReactがDOMを構築するまでの流れを知りましょう。
以下のコードがあります。※伝えたいことのためにエラーハンドリング等は省いています。
import React, { useState, useEffect } from "react";
const fetchName = async () => {
const response = await fetch("http://example.com/api/name");
// ・・・取得した名前「太郎」を返すAPI
return response.json().name;
};
export const Test = () => {
const [name, setName] = useState("");
useEffect(() => {
const fetchData = async () => {
const nameData = await fetchName();
setName(nameData);
};
fetchData();
}, []);
return (
<>
<p>{`apiで呼び出した名前: ${name}`}</p>
</>
);
};
上記はどのような順番で処理が実行されるでしょうか。
関数はまず初めに以下のようなDOMを構築します。
apiで呼び出した名前:
※空文字
これはuseEffectが最初のDOM構築の後に実行される、と言う性質のため起こる結果です。
イメージで言うと先ほどの関数から以下の部分のみを実行したようなものです。
export const Test = () => {
const [name, setName] = useState("")
return (
<>
<p>{`apiで呼び出した名前: ${name}`}</p>
</>
)
}
最初のDOM構築時点でuseEffectは実行されないので、nameの値はuseState("")部分で定義した初期値の空文字になります。そして「apiで呼び出した名前: (空文字)」がDOMへ反映された後、useEffect内の以下の部分が動きます。
const fetchName = async () => {
const response = await fetch("http://example.com/api/name");
// ・・・取得した名前「太郎」を返すAPI
return response.json().name;
};
const [name, setName] = useState("")
useEffect(() => {
const fetchData = async () => {
const nameData = await fetchName();
setName(nameData);
};
fetchData();
}, []);
ここで初めてfetchが行われ、setNameに取得した値がセットされます。そしてこの後Reactは再度DOMを構築します。すると出力結果は以下です。
apiで呼び出した名前: 太郎
useEffectの中身が実行され、setName(nameData)
の部分で更新されています。では、ここまでのレンダリングの流れで最低限この流れがわかれば理解が進むことを書きます。
useEffectが実行されるまでの流れ
s1. ReactはuseEffect以外の部分を読み取ってDOMを構築します。(初期レンダリング)
2. useEffectの中身を実行、完了後3へ
3. 再レンダリング(DOMの再構築)を行い、2の実行結果がDOMへ反映される。
このような流れになります。
タイミングの感覚だけでも掴んでもらえれば十分です!
お次はそもそもなぜuseEffectが必要なの?
useEffectの第二引数にある配列[]って何?
などについて書ければと思います。
独学でまだまだわからないことだらけなのでエンジニアの皆様方ご指摘等ぜひお待ちしておりますm(__)m