🤔
データ取得にはuseEffectよりuseSWRを使用しよう
はじめに
データ取得においてuseEffectの副作用を利用してデータ取得を行うものをよく見かけるがuseEffectを利用するよりももっと良い書き方があるのでまとめておきます。
useEffectでよく使用する書き方
'use client';
import { useState, useEffect } from 'react';
interface User {
id: number
email: string
name: string
username: string
phone: string
website: string
}
const Home = () => {
const [user, setUser] = useState<User | null>(null);
const [error, setError] = useState<string | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(false);
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users/1');
if (!response.ok) {
throw new Error('Some Error');
}
const data = await response.json();
setUser(data);
} catch (error: unknown) {
if (error instanceof Error) {
setError(error.message);
}
setUser(null);
}
setIsLoading(false);
}
fetchData();
}, []);
if (error) return <div>Load is Faild</div>
if (isLoading) return <div>Loading...</div>
return (
<>
<div>
<ul>
<li>お名前:{user?.name}</li>
<li>メールアドレス:{user?.email}</li>
</ul>
</div>
</>
)
}
export default Home;
デメリット
-
コードが煩雑になってしまうこと。
- ロジックが複雑になってしまう。
- 状態を複数持たないといけない。
- エラーハンドリングが長文になってしまう。
-
キャッシュができていない。
- リロードするたびにサーバーからデータを取得している。
※ キャッシュとは、データをブラウザのメモリに一時的に保存することです。キャッシュをすることでブラウザにデータが残っているので毎回サーバーにアクセスすることがなく高速化に繋がる。
useSWRで書くとどうなるのか
'use client';
import useSWR from 'swr';
interface User {
id: number
email: string
name: string
username: string
phone: string
website: string
}
async function fetcher(key: string): Promise<User> {
return fetch(key).then((response) => response.json());
}
const Home = () => {
const {data, error, isLoading} = useSWR('https://jsonplaceholder.typicode.com/users/1', fetcher);
if (error) return <div>Load is Faild</div>
if (isLoading) return <div>Loading...</div>
return (
<>
<div>
<ul>
<li>お名前:{data?.name}</li>
<li>メールアドレス:{data?.email}</li>
</ul>
</div>
</>
)
}
export default Home;
メリット
- コード量が少なくなり可読性が向上。
- キャッシュがされているので高速化にも繋がる
参考
Discussion