ホームページ  >  記事  >  ウェブフロントエンド  >  Axios と React Query を使用した React CRUD 操作

Axios と React Query を使用した React CRUD 操作

Patricia Arquette
Patricia Arquetteオリジナル
2024-09-24 20:30:40359ブラウズ

React CRUD Operations with Axios and React Query

前の記事「カスタム フックを使用した React での HTTP リクエストの簡素化?」では、カスタム フックを使用して HTTP リクエストを簡素化する方法を検討しました。このアプローチは小規模なアプリケーションには効果的ですが、React アプリがスケールするにつれて維持するのが難しくなる可能性があります。この記事では、Axios と React Query を使用して CRUD (作成、読み取り、更新、削除) 操作をスケーラブルな方法で処理する方法について詳しく説明します。

Axios と React Query を使用する理由

  • Axios: ブラウザーおよび Node.js 用の Promise ベースの HTTP クライアントである Axios は、クリーンで読みやすいコードで REST エンドポイントへの非同期 HTTP リクエストの送信を簡素化します。

  • React Query: React でのデータ同期、キャッシュ、状態管理を強化する強力なデータ取得ライブラリです。 React Query は、データの取得を自動化しながら、読み込みとエラーの状態をより適切に制御します。

Axios と React Query のセットアップ

まず、必要なパッケージをインストールします。

npm install axios react-query react-router-dom

アプリでの React Query の設定

次に、エントリ ファイル (App.tsx) で React Query を構成して、アプリケーションのグローバル クエリ設定を管理します。

// src/App.tsx
import { QueryClient, QueryClientProvider } from 'react-query';
import { CustomRouter } from './Router';

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      refetchOnWindowFocus: false,  // Prevent refetch on tab/window switch
      retry: 1,                     // Retry failed queries once
    },
  },
});

const App: React.FC = () => (
  <QueryClientProvider client={queryClient}>
    <CustomRouter />
  </QueryClientProvider>
);

export default App;

インターセプターを使用した Axios のセットアップ

認証をグローバルに処理するには、Axios インスタンスを作成し、インターセプターを使用して認証されたリクエストの Authorization ヘッダーを添付します。

// src/config/axiosApi.ts
import axios from 'axios';

const authenticatedApi = axios.create({
  baseURL: import.meta.env.VITE_BASE_URL,  // Environment-specific base URL
  headers: {
    'Content-Type': 'application/json',
  },
});

// Attach Authorization token to requests if present
authenticatedApi.interceptors.request.use((config) => {
  const token = localStorage.getItem('crud-app-auth-token');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

export { authenticatedApi };

CRUD操作用のAPI関数の作成

Axios を使用して CRUD 操作を実行するために API と対話する関数を定義しましょう:

// src/data/api/post.ts
import { authenticatedApi } from '../../config/axiosApi';

// Error handler function to standardize error messages
export const handleApiError = (error: any): never => {
  if (error.message === 'Network Error') {
    throw new Error('Network Error. Please try again later.');
  } else if (error.response?.data?.error) {
    throw new Error(error.response.data.error);
  } else if (error.response) {
    throw new Error('A server error occurred.');
  } else {
    throw new Error(error.message || 'An unknown error occurred.');
  }
};

// General function to handle API requests
export const apiCall = async <T>(
  method: 'get' | 'post' | 'put' | 'delete',
  url: string,
  data?: any,
): Promise<T> => {
  try {
    const response = await authenticatedApi[method](url, data);
    return response.data;
  } catch (error) {
    throw handleApiError(error);
  }
};

// CRUD functions for the post feed
export const createPostApi = (post: any) => apiCall<any>('post', 'posts', post);
export const getPostsApi = () => apiCall<any>('get', 'posts');
export const updatePostApi = (id: string, post: any) => apiCall<any>('put', `posts/${id}`, post);
export const deletePostApi = (id: string) => apiCall<any>('delete', `posts/${id}`);

CRUD 操作に React クエリ フックを使用する

API 関数を用意したので、React Query を使用してこれらの操作の状態管理とデータの取得を処理できます。

// src/data/hooks/post.ts
import { useMutation, useQuery, useQueryClient } from 'react-query';
import { createPostApi, getPostsApi, updatePostApi, deletePostApi } from '../api/post';

// Custom hooks for CRUD operations
export const useCreatePostApi = () => {
  const queryClient = useQueryClient();
  return useMutation(createPostApi, {
    onSuccess: () => queryClient.invalidateQueries(['posts']), // Refetch posts after a new post is created
  });
};

export const useGetPostsApi = () => useQuery(['posts'], getPostsApi);

export const useUpdatePostApi = () => {
  const queryClient = useQueryClient();
  return useMutation(updatePostApi, {
    onSuccess: () => queryClient.invalidateQueries(['posts']), // Refetch posts after an update
  });
};

export const useDeletePostApi = () => {
  const queryClient = useQueryClient();
  return useMutation(deletePostApi, {
    onSuccess: () => queryClient.invalidateQueries(['posts']), // Refetch posts after deletion
  });
};

コンポーネント内の CRUD フックの使用

最後に、カスタム フックを使用し、ユーザーが投稿を作成、編集、削除できるようにする単純なコンポーネントを構築できます。

// src/components/PostCard.tsx
import React, { useState } from 'react';
import { useGetPostsApi, useDeletePostApi, useUpdatePostApi, useCreatePostApi } from '../data/hooks/post';
import { toast } from '../components/Toast';  // Assume a toast component exists

const PostCard: React.FC = () => {
  const { data: posts, isLoading, error } = useGetPostsApi();
  const deletePost = useDeletePostApi();
  const updatePost = useUpdatePostApi();
  const createPost = useCreatePostApi();
  const [newPost, setNewPost] = useState({ title: '', content: '' });

  const handleCreate = async () => {
    try {
      await createPost.mutateAsync(newPost);
      setNewPost({ title: '', content: '' });
      toast.success('Post created successfully');
    } catch (error) {
      toast.error(error.message);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      await deletePost.mutateAsync(id);
      toast.success('Post deleted successfully');
    } catch (error) {
      toast.error(error.message);
    }
  };

  const handleEdit = async (id: string, updatedPost: any) => {
    try {
      await updatePost.mutateAsync({ id, ...updatedPost });
      toast.success('Post updated successfully');
    } catch (error) {
      toast.error(error.message);
    }
  };

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <div>
        <input
          type="text"
          value={newPost.title}
          onChange={(e) => setNewPost({ ...newPost, title: e.target.value })}
          placeholder="Title"
        />
        <input
          type="text"
          value={newPost.content}
          onChange={(e) => setNewPost({ ...newPost, content: e.target.value })}
          placeholder="Content"
        />
        <button onClick={handleCreate} disabled={createPost.isLoading}>
          {createPost.isLoading ? 'Creating...' : 'Create Post'}
        </button>
      </div>

      {posts?.map((post: any) => (
        <div key={post.id}>
          <h3>{post.title}</h3>
          <p>{post.content}</p>
          <button onClick={() => handleEdit(post.id, { title: 'Updated Title', content: 'Updated Content' })}>
            Edit
          </button>
          <button onClick={() => handleDelete(post.id)}>
            Delete
          </button>
        </div>
      ))}
    </div>
  );
};

export default PostCard;

結論

Axios と React Query を使用すると、React アプリケーションでの CRUD 操作を合理化できます。この組み合わせにより、クリーンで保守しやすいコードが得られ、スケーラビリティとパフォーマンスが向上します。これらのツールを使用すると、アプリの成長に合わせて状態管理とデータの取得を簡素化できます。

React、TypeScript、最新の Web 開発実践についてさらに詳しく知りたい場合は、Dev.to で私をフォローしてください。 ?‍?

以上がAxios と React Query を使用した React CRUD 操作の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。