2025.05.12
【Next】SWRを使う場合、使わない場合の違い

Image by Jill Wellington from Pixabay

はじめに

SWRがどれだけ便利かがいまいちわからなかったので、
使わなかった場合とのコードを比較しました。

前提

※急いでいる方は、以下の内容はスキップして、「コードの比較」をご覧ください。

 

Ajax通信用の関数を以下のように定義し、
その関数を使用して、

・SWRを使う場合
・SWRを使わない場合

のGETの処理のコードを比較します。

 

Ajax通信用の関数は以下です。

// 共通のAjax通信関数「fetcher」を作成
const fetcher = async (
  url: string,                                  // 通信先のURL
  methodVal: 'GET' | 'POST' | 'PUT' | 'DELETE', // HTTPリクエストメソッド
  body?: any                                    // POST,PUTの場合のHTTPリクエストボディの値
) => {

  // 送信先URLのベース
  const toUrl = "http://localhost:8000";

  // 通信処理
  const response = await fetch(`${toUrl}/${url}`, {
    method: methodVal,        // HTTPリクエストメソッドを設定
    credentials: 'include',   // Cookieを送る

    // HTTPリクエストのヘッダー情報を設定
    headers: {
      'Content-Type': 'application/json',
      'X-Requested-With': 'XMLHttpRequest',         // Ajax通信であることを伝える
    },
    body: body ? JSON.stringify(body) : undefined,  // bodyの設定
  });

  // 通信エラーの場合の処理
  if(!response.ok){
    throw new Error('エラーが発生しました');
  }

  // 取得したデータをJSON形式に変換して渡す
  return response.json();
}

export default fetcher;

コードの比較

■SWRを使う場合

'use client';
import useSWR from 'swr';
import fetcher from '@/libs/fetcher'; // fetcher(url, method)

export default function PostList() {

  // この個所のコードに違いがあります////////////
  const { data, error, isLoading } = useSWR('/api/posts', (url) => fetcher(url, 'GET'));
  // ↑↑ /////////////////////////////////////

  if (isLoading) return <div>読み込み中...</div>;
  if (error) return <div>データ取得中にエラーが発生しました</div>;

  return (
    <ul>
      {data.map((post: any) => (
        <li key={post.id}>{post.text}</li>
      ))}
    </ul>
  );
}

■SWRを使わない場合

'use client';
import React, { useEffect, useState } from 'react';
import fetcher from '@/libs/fetcher'; // fetcher(url, method)

export default function PostList() {

  // ↓↓ 以下の範囲がSWRを使うと1行で済みます ↓↓  //
  const [posts, setPosts] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  
  useEffect(() => {
    const loadPosts = async () => {
      try {
        const data = await fetcher('/api/posts', 'GET');
        setPosts(data);
      } catch (err) {
        setError('データ取得中にエラーが発生しました');
      } finally {
        setLoading(false);
      }
    };

    loadPosts();
  }, []);
  // ↑↑ ここまで ↑↑ ////////////////////////////////////////

  if (loading) return <div>読み込み中...</div>;
  if (error) return <div>{error}</div>;

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.text}</li>
      ))}
    </ul>
  );
}

結論

SWRを使うと、useEffect, try-catchの処理を内部的にやってくれるので、

とてもシンプルにコーディングできました。

 

以上です。