useEffectとは
『useEffect』を使うと、『useEffect』に渡された関数はレンダーの結果が画面に反映された後に動作する。つまりuseEffectとは、「関数の実行タイミングをReactのレンダリング後まで遅らせるhook」の事。
副作用の処理(DOMの書き換え、変数代入、API通信などUI構築以外の処理)を関数コンポーネントで扱える。
副作用を実行、制御するためにuseEffectを利用する
useEffect(() => {
/* 第1引数には実行させたい副作用関数を記述*/
console.log('副作用関数が実行されました!')
},[依存する変数の配列])
// 第2引数には副作用関数の実行タイミングを制御する依存データを記述
第2引数を指定することにより、第1引数に渡された副作用関数の実行タイミングを制御することができる。Reactは第2引数の依存配列の中身の値を比較して、副作用関数をスキップするかどうかを判断する。
説明 | データ型 | |
---|---|---|
第1引数 | 副作用関数(戻り値はクリーンアップ関数、または何も返さない) | 関数 |
第2引数 | 副作用関数の実行タイミングを制御する依存データが入る(省略可能) | 配列 |
useEffectでの外部からデータをfetchする方法
外部のサーバのやりとりにuseEffectを利用する場合は第2引数にをつけるのを忘れないこと。配列をつけていない場合はコンポーネントの更新によりuseEffectが実行され、サーバへのFetchが継続して行われることになりサーバへの負荷をかけることになる。ネットワーク処理がブラウザ上では気づかない場合があるのでブラウザ上ではなにも発生していないのにすごい数のリクエストがサーバに送信されていることがある。
import React,{ useState, useEffect} from 'react';
import './App.css';
function App() {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then(response => response.json())
.then(data => {
setPosts(data)
},[])
})
return (
<div className="App">
<h1>Learn useEffect</h1>
<div>
{
posts.map(post => (
<div key={post.id}>{post.title}</div>
))
}
</div>
</div>
);
}
useStateを使ってstata変数postsを定義し、初期値を空の配列に設定する。マウント後にuseEffect内のfetchメソッドが実行され、JSONPLACEHOLDERのURLにアクセスを行いpostsデータ一覧を取得。取得したデータはsetPostでposts変数に挿入し、最後にmapメソッドで展開し、ブラウザに一覧を表示する。
async, awaitを利用して外部から取得する場合
useEffectでasync, awaitを利用して外部リソースからデータを取得したい場合は下記のように記述することができる。
import React,{ useState, useEffect} from 'react';
import './App.css';
function App() {
const [posts, setPosts] = useState([]);
useEffect(() => {
const fetchPost = async () => {
const response = await fetch(
'https://jsonplaceholder.typicode.com/posts'
);
const posts = await response.json();
setPosts(posts);
};
fetchPost();
})
return (
<div className="App">
<h1>Learn useEffect</h1>
<div>
{
posts.map(post => (
<div key={post.id}>{post.title}</div>
))
}
</div>
</div>
);
}
export default App;