Dalam artikel sebelumnya, Mempermudahkan Permintaan HTTP dalam React dengan Custom Hooks ?, kami meneroka cara untuk memudahkan permintaan HTTP menggunakan kait tersuai. Walaupun berkesan untuk aplikasi yang lebih kecil, pendekatan ini mungkin menjadi lebih sukar untuk dikekalkan apabila apl React anda berskala. Dalam artikel ini, kita akan menyelami cara mengendalikan operasi CRUD (Buat, Baca, Kemas Kini, Padam) dalam cara berskala menggunakan Axios dan React Query.
Axios: Pelanggan HTTP berasaskan janji untuk penyemak imbas dan Node.js, Axios memudahkan penghantaran permintaan HTTP tak segerak ke titik akhir REST dengan kod yang bersih dan boleh dibaca.
React Query: Pustaka pengambilan data yang berkuasa yang mempertingkatkan penyegerakan data, caching dan pengurusan keadaan dalam React. React Query mengautomasikan pengambilan data sambil menyediakan kawalan yang lebih baik ke atas keadaan pemuatan dan ralat.
Mula-mula, pasang pakej yang diperlukan:
npm install axios react-query react-router-dom
Seterusnya, konfigurasikan React Query dalam fail masukan anda (App.tsx) untuk mengurus tetapan pertanyaan global aplikasi anda.
// 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;
Untuk mengendalikan pengesahan secara global, kami boleh mencipta tika Axios dan menggunakan pemintas untuk melampirkan pengepala Kebenaran untuk permintaan yang disahkan.
// 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 };
Mari tentukan fungsi yang berinteraksi dengan API kami untuk melaksanakan operasi CRUD menggunakan Axios:
// 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}`);
Sekarang kami mempunyai fungsi API, kami boleh menggunakan React Query untuk mengendalikan pengurusan keadaan dan pengambilan data untuk operasi ini.
// 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 }); };
Akhir sekali, kami boleh membina komponen mudah yang menggunakan cangkuk tersuai dan membolehkan pengguna membuat, mengedit dan memadamkan siaran.
// 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;
Dengan menggunakan Axios dan React Query, anda boleh menyelaraskan operasi CRUD dalam aplikasi React anda. Gabungan ini menghasilkan kod yang bersih, boleh diselenggara, meningkatkan kebolehskalaan dan prestasi. Gunakan alatan ini untuk memudahkan pengurusan negeri dan pengambilan data semasa apl anda berkembang.
Untuk mendapatkan lebih banyak cerapan tentang React, TypeScript dan amalan pembangunan web moden, ikuti saya di Dev.to! ?
Atas ialah kandungan terperinci React Operasi CRUD dengan Axios dan React Query. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!