🐥
【React】useEffectとuseSWRをシンプルなコードで比較してみた
はじめに
useEffectよりシンプルに実装できるuseSWRなるものを知り、どんな違いがあるのか気になったため簡単なコードで両者を比べてみました。
フォルダ&ファイル構成
src/
├── components/
│ ├── UserListEffect.tsx
│ └── UserListSWR.tsx
├── App.tsx
└── index.tsx
サンプルプロジェクトの準備
# プロジェクト作成して移動
npx create-react-app swr-vs-useeffect --template typescript
cd swr-vs-useeffect
# SWRをインポート
npm install swr
ファイルを作成
UserListEffect.tsx
import { useEffect, useState } from 'react';
type User = {
id: number;
name: string;
};
export const UserListEffect = () => {
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchUsers = async () => {
try {
const res = await fetch('https://jsonplaceholder.typicode.com/users');
if (!res.ok) throw new Error('データ取得失敗');
const data: User[] = await res.json();
setUsers(data);
} catch (err) {
setError((err as Error).message);
} finally {
setLoading(false);
}
};
fetchUsers();
}, []);
if (loading) return <p>読み込み中...</p>;
if (error) return <p>エラー: {error}</p>;
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
UserListSWR.tsx
import useSWR from 'swr';
type User = {
id: number;
name: string;
};
const fetcher = (url: string) => fetch(url).then(res => res.json());
export const UserListSWR = () => {
const { data, error, isLoading } = useSWR<User[]>(
'https://jsonplaceholder.typicode.com/users',
fetcher
);
if (isLoading) return <p>読み込み中...</p>;
if (error) return <p>エラー: {error.message}</p>;
return (
<ul>
{data?.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
ブラウザでの表示
比較まとめ
比較項目 | useEffect + fetch | useSWR |
---|---|---|
実装方法 | 自分でfetch処理を書く | 短いコードでOK |
エラーハンドリング | try-catchで自分で処理 |
error が勝手に用意される |
キャッシュ | なし | 自動でキャッシュ |
再取得 | 自分でロジックを書く必要 | 自動(フォーカス時・ネット復帰時など) |
非同期処理の扱い方 |
async/await で自前 |
useSWR内部でやってくれる |
参考
Discussion