سادهسازی واکشی دادهها با Zustand و Tanstack Query: یک خط برای کنترل همه آنها

Summarize this content to 400 words in Persian Lang
در توسعه وب مدرن، مدیریت واکشی دادهها، وضعیتهای بارگیری و مدیریت خطا میتواند به سرعت پیچیده و پرمخاطب شود. با این حال، با ابزارهای مناسب و کمی انتزاع، می توانیم این روند را به طور قابل توجهی ساده کنیم. در این پست وبلاگ، به شما نشان خواهم داد که چگونه از Zustand برای مدیریت حالت و Tanstack Query (که قبلا React Query نامیده می شد) استفاده کردم تا تمام این پیچیدگی را به یک خط کد در اجزای React خود کاهش دهم.
مشکل
به طور معمول، هنگام واکشی داده ها در یک جزء React، باید چندین حالت را مدیریت کنید:
داده های واکشی شده
وضعیت بارگیری
حالت خطا
همچنین باید منطق واکشی واقعی دادهها، مدیریت خطا، و به طور بالقوه راهی برای بازیابی دادهها را اجرا کنید. این می تواند منجر به کدهای دیگ بخار زیادی در قطعات شما شود.
راه حل
با استفاده از Zustand برای مدیریت حالت، Tanstack Query برای واکشی دادهها، و ایجاد یک سیستم اعلان تست متمرکز، میتوانیم همه این منطق را کپسوله کنیم و یک API ساده و تمیز را در اختیار اجزای خود قرار دهیم. در اینجا نحوه انجام این کار آمده است:
مرحله 1: فروشگاه Zustand را راه اندازی کنید
ابتدا یک فروشگاه Zustand برای مدیریت وضعیت بارگیری جهانی خود ایجاد می کنیم:
import { create } from ‘zustand’;
interface LoaderState {
isLoading: boolean;
setIsLoading: (isLoading: boolean) => void;
}
export const useLoaderStore = createLoaderState>()((set) => ({
isLoading: false,
setIsLoading: (isLoading: boolean) => set({ isLoading }),
}));
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
ما از Zustand استفاده می کنیم زیرا راه حلی ساده و سبک برای مدیریت وضعیت جهانی ارائه می دهد. در این مورد، ما از آن برای مدیریت یک وضعیت بارگیری جهانی استفاده میکنیم که میتوان از هر جایی در برنامه ما به آن دسترسی داشت و آن را تغییر داد.
مرحله 2: ReactQueryProvider را با Global Toast راه اندازی کنید
ما یک ReactQueryProvider راه اندازی کردیم که شامل یک سیستم نان تست جهانی است:
import React, { useRef } from ‘react’;
import { MutationCache, QueryCache, QueryClient, QueryClientProvider } from ‘@tanstack/react-query’;
import { Toast } from ‘primereact/toast’;
import { TOAST_SEVERITY } from ‘@/app/ts/constants/ui’;
let globalToast: React.RefObjectToast> | null = null;
export const showToast = (severity: TOAST_SEVERITY, summary: string, detail: string, life: number = 5000) => {
globalToast?.current?.show({ severity, summary, detail, life });
};
export function ReactQueryProvider({ children }: React.PropsWithChildren) {
const toastRef = useRefToast>(null);
globalToast = toastRef;
const queryClient = new QueryClient({
queryCache: new QueryCache({
onError: (error: any, query) => {
console.error(JSON.stringify(error));
},
}),
mutationCache: new MutationCache({
onError: (error: any, query) => {
console.error(JSON.stringify(error));
},
}),
});
return (
QueryClientProvider client={queryClient}>
Toast ref={toastRef} />
{children}
/QueryClientProvider>
);
}
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
این تنظیمات جهانی را فراهم می کند showToast عملکردی که می تواند در هر نقطه از برنامه برای نمایش اعلان های نان تست استفاده شود.
مرحله 3: ایجاد عملکرد اعلان خطا
ما یک تابع اعلان خطای متمرکز ایجاد می کنیم:
import { TOAST_SEVERITY } from ‘@/app/ts/constants/ui’;
import { showToast } from ‘@/providers/ReactQueryProvider’;
import { CustomError } from ‘@/app/ts/interfaces/global/customError’;
export const errorNotification = (isError: boolean, title: string, error: CustomError | null = null) => {
if (isError && error) {
showToast(TOAST_SEVERITY.ERROR, `${error.status}: ${title}`, error.message, 5000);
}
};
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
مرحله 4: یک هوک سفارشی برای اعلان خطا ایجاد کنید
ما یک قلاب سفارشی برای رسیدگی به اعلانهای خطا ایجاد میکنیم:
import { useEffect } from ‘react’;
import { errorNotification } from ‘@/app/functions/errorResponse’;
import { CustomError } from ‘@/app/ts/interfaces/global/customError’;
export const useErrorNotification = (isError: boolean, title: string, error: CustomError | null = null) => {
useEffect(() => {
errorNotification(isError, title, error);
}, [isError]);
};
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
مرحله 5: یک قلاب واکشی داده های سفارشی ایجاد کنید
ما یک قلاب سفارشی برای واکشی داده ها، در این مورد، برای خودروها ایجاد می کنیم:
import { useQuery } from ‘@tanstack/react-query’;
import { CarApi } from ‘@/app/api/carApi’;
import { CARS } from ‘@/app/ts/constants/process’;
import { useDataFetching } from ‘@/hooks/useDataFetching’;
import { useQueryProps } from ‘@/app/ts/interfaces/configs/types’;
import { ERROR_FETCHING_CARS } from ‘@/app/ts/constants/messages’;
export const useCars = ({ filterObject = undefined, active = false, enabled = true }: useQueryProps) => {
const errorMessage = ERROR_FETCHING_CARS;
const getFilteredCars = async () => {
if (Object.keys(filterObject || {}).length === 0 || filterObject === undefined) return await CarApi.getActiveCars();
return await CarApi.getCarsWithSpecificBrand(filterObject.id, active);
};
const {
data: cars,
isLoading: isLoadingCars,
refetch: refetchCars,
error: errorCars,
isError: isErrorCars,
} = useQuery({
queryKey: [CARS],
queryFn: getFilteredCars,
retry: 0,
enabled,
});
useDataFetching({ isLoading: isLoadingCars, isError: isErrorCars, error: errorCars, errorMessage });
return { cars, isLoadingCars, refetchCars, errorCars };
};
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
مرحله 6: از قلاب سفارشی در کامپوننت خود استفاده کنید
اکنون، در کامپوننت خود، می توانید از هوک سفارشی با یک خط کد استفاده کنید:
const { cars, refetchCars } = useCars({ filterObject: selectedBrand, active });
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
این یک خط به شما امکان دسترسی به موارد زیر را می دهد:
داده های واکشی شده (cars)
تابعی برای بازیابی داده ها (refetchCars)
مدیریت حالت بارگیری خودکار (با استفاده از Zustand)
رسیدگی و اطلاع رسانی خودکار خطا (با استفاده از سیستم نان تست جهانی)
مزایا
با استفاده از این رویکرد با Zustand و Tanstack Query، ما چندین مزیت را به دست آورده ایم:
کد کامپوننت ساده شده: اجزای ما اکنون بسیار تمیزتر هستند و بر روی رندر متمرکز شده اند، نه مدیریت داده ها.
مدیریت جهانی دولت: Zustand یک راه آسان برای مدیریت وضعیت جهانی، مانند نشانگر بارگیری ما، ارائه می دهد.
واکشی قدرتمند داده ها: Tanstack Query بهروزرسانیهای ذخیرهسازی، واکشی مجدد و پسزمینه را با حداقل پیکربندی مدیریت میکند.
مدیریت خطای متمرکز: سیستم نان تست جهانی ما روشی ثابت برای رسیدگی و نمایش خطاها ارائه می دهد.
قابلیت استفاده مجدد: useCars قلاب را می توان در هر مؤلفه ای که نیاز به واکشی اطلاعات خودرو دارد استفاده کرد.
ثبات: مدیریت خطا و حالت های بارگیری به طور مداوم در تمام اجزا با استفاده از این قلاب مدیریت می شود.
بازیابی آسان: اگر نیاز به واکشی مجدد داده ها داشته باشیم (مثلاً پس از به روز رسانی)، می توانیم به سادگی تماس بگیریم refetchCars().
نتیجه
با استفاده از Zustand برای مدیریت ایالت، Tanstack Query برای واکشی داده ها، و ایجاد یک سیستم اعلان نان تست متمرکز، فرآیند واکشی داده های خود را به طور قابل توجهی ساده کرده ایم. این رویکرد به ما اجازه می دهد تا وظایف پیچیده مدیریت داده را با یک خط کد در اجزای خود انجام دهیم که منجر به برنامه های React تمیزتر و قابل نگهداری تر می شود.
به یاد داشته باشید، کلید این ساده سازی، انتقال پیچیدگی به قلاب هایی با طراحی خوب و قابل استفاده مجدد و استفاده از کتابخانه های قدرتمندی مانند Zustand و Tanstack Query است. به این ترتیب، ما یک بار مشکل را حل می کنیم و از راه حل در کل برنامه خود بهره مند می شویم.
در توسعه وب مدرن، مدیریت واکشی دادهها، وضعیتهای بارگیری و مدیریت خطا میتواند به سرعت پیچیده و پرمخاطب شود. با این حال، با ابزارهای مناسب و کمی انتزاع، می توانیم این روند را به طور قابل توجهی ساده کنیم. در این پست وبلاگ، به شما نشان خواهم داد که چگونه از Zustand برای مدیریت حالت و Tanstack Query (که قبلا React Query نامیده می شد) استفاده کردم تا تمام این پیچیدگی را به یک خط کد در اجزای React خود کاهش دهم.
مشکل
به طور معمول، هنگام واکشی داده ها در یک جزء React، باید چندین حالت را مدیریت کنید:
- داده های واکشی شده
- وضعیت بارگیری
- حالت خطا
همچنین باید منطق واکشی واقعی دادهها، مدیریت خطا، و به طور بالقوه راهی برای بازیابی دادهها را اجرا کنید. این می تواند منجر به کدهای دیگ بخار زیادی در قطعات شما شود.
راه حل
با استفاده از Zustand برای مدیریت حالت، Tanstack Query برای واکشی دادهها، و ایجاد یک سیستم اعلان تست متمرکز، میتوانیم همه این منطق را کپسوله کنیم و یک API ساده و تمیز را در اختیار اجزای خود قرار دهیم. در اینجا نحوه انجام این کار آمده است:
مرحله 1: فروشگاه Zustand را راه اندازی کنید
ابتدا یک فروشگاه Zustand برای مدیریت وضعیت بارگیری جهانی خود ایجاد می کنیم:
import { create } from 'zustand';
interface LoaderState {
isLoading: boolean;
setIsLoading: (isLoading: boolean) => void;
}
export const useLoaderStore = createLoaderState>()((set) => ({
isLoading: false,
setIsLoading: (isLoading: boolean) => set({ isLoading }),
}));
ما از Zustand استفاده می کنیم زیرا راه حلی ساده و سبک برای مدیریت وضعیت جهانی ارائه می دهد. در این مورد، ما از آن برای مدیریت یک وضعیت بارگیری جهانی استفاده میکنیم که میتوان از هر جایی در برنامه ما به آن دسترسی داشت و آن را تغییر داد.
مرحله 2: ReactQueryProvider را با Global Toast راه اندازی کنید
ما یک ReactQueryProvider راه اندازی کردیم که شامل یک سیستم نان تست جهانی است:
import React, { useRef } from 'react';
import { MutationCache, QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { Toast } from 'primereact/toast';
import { TOAST_SEVERITY } from '@/app/ts/constants/ui';
let globalToast: React.RefObjectToast> | null = null;
export const showToast = (severity: TOAST_SEVERITY, summary: string, detail: string, life: number = 5000) => {
globalToast?.current?.show({ severity, summary, detail, life });
};
export function ReactQueryProvider({ children }: React.PropsWithChildren) {
const toastRef = useRefToast>(null);
globalToast = toastRef;
const queryClient = new QueryClient({
queryCache: new QueryCache({
onError: (error: any, query) => {
console.error(JSON.stringify(error));
},
}),
mutationCache: new MutationCache({
onError: (error: any, query) => {
console.error(JSON.stringify(error));
},
}),
});
return (
QueryClientProvider client={queryClient}>
Toast ref={toastRef} />
{children}
/QueryClientProvider>
);
}
این تنظیمات جهانی را فراهم می کند showToast
عملکردی که می تواند در هر نقطه از برنامه برای نمایش اعلان های نان تست استفاده شود.
مرحله 3: ایجاد عملکرد اعلان خطا
ما یک تابع اعلان خطای متمرکز ایجاد می کنیم:
import { TOAST_SEVERITY } from '@/app/ts/constants/ui';
import { showToast } from '@/providers/ReactQueryProvider';
import { CustomError } from '@/app/ts/interfaces/global/customError';
export const errorNotification = (isError: boolean, title: string, error: CustomError | null = null) => {
if (isError && error) {
showToast(TOAST_SEVERITY.ERROR, `${error.status}: ${title}`, error.message, 5000);
}
};
مرحله 4: یک هوک سفارشی برای اعلان خطا ایجاد کنید
ما یک قلاب سفارشی برای رسیدگی به اعلانهای خطا ایجاد میکنیم:
import { useEffect } from 'react';
import { errorNotification } from '@/app/functions/errorResponse';
import { CustomError } from '@/app/ts/interfaces/global/customError';
export const useErrorNotification = (isError: boolean, title: string, error: CustomError | null = null) => {
useEffect(() => {
errorNotification(isError, title, error);
}, [isError]);
};
مرحله 5: یک قلاب واکشی داده های سفارشی ایجاد کنید
ما یک قلاب سفارشی برای واکشی داده ها، در این مورد، برای خودروها ایجاد می کنیم:
import { useQuery } from '@tanstack/react-query';
import { CarApi } from '@/app/api/carApi';
import { CARS } from '@/app/ts/constants/process';
import { useDataFetching } from '@/hooks/useDataFetching';
import { useQueryProps } from '@/app/ts/interfaces/configs/types';
import { ERROR_FETCHING_CARS } from '@/app/ts/constants/messages';
export const useCars = ({ filterObject = undefined, active = false, enabled = true }: useQueryProps) => {
const errorMessage = ERROR_FETCHING_CARS;
const getFilteredCars = async () => {
if (Object.keys(filterObject || {}).length === 0 || filterObject === undefined) return await CarApi.getActiveCars();
return await CarApi.getCarsWithSpecificBrand(filterObject.id, active);
};
const {
data: cars,
isLoading: isLoadingCars,
refetch: refetchCars,
error: errorCars,
isError: isErrorCars,
} = useQuery({
queryKey: [CARS],
queryFn: getFilteredCars,
retry: 0,
enabled,
});
useDataFetching({ isLoading: isLoadingCars, isError: isErrorCars, error: errorCars, errorMessage });
return { cars, isLoadingCars, refetchCars, errorCars };
};
مرحله 6: از قلاب سفارشی در کامپوننت خود استفاده کنید
اکنون، در کامپوننت خود، می توانید از هوک سفارشی با یک خط کد استفاده کنید:
const { cars, refetchCars } = useCars({ filterObject: selectedBrand, active });
این یک خط به شما امکان دسترسی به موارد زیر را می دهد:
- داده های واکشی شده (
cars
) - تابعی برای بازیابی داده ها (
refetchCars
) - مدیریت حالت بارگیری خودکار (با استفاده از Zustand)
- رسیدگی و اطلاع رسانی خودکار خطا (با استفاده از سیستم نان تست جهانی)
مزایا
با استفاده از این رویکرد با Zustand و Tanstack Query، ما چندین مزیت را به دست آورده ایم:
- کد کامپوننت ساده شده: اجزای ما اکنون بسیار تمیزتر هستند و بر روی رندر متمرکز شده اند، نه مدیریت داده ها.
- مدیریت جهانی دولت: Zustand یک راه آسان برای مدیریت وضعیت جهانی، مانند نشانگر بارگیری ما، ارائه می دهد.
- واکشی قدرتمند داده ها: Tanstack Query بهروزرسانیهای ذخیرهسازی، واکشی مجدد و پسزمینه را با حداقل پیکربندی مدیریت میکند.
- مدیریت خطای متمرکز: سیستم نان تست جهانی ما روشی ثابت برای رسیدگی و نمایش خطاها ارائه می دهد.
-
قابلیت استفاده مجدد:
useCars
قلاب را می توان در هر مؤلفه ای که نیاز به واکشی اطلاعات خودرو دارد استفاده کرد. - ثبات: مدیریت خطا و حالت های بارگیری به طور مداوم در تمام اجزا با استفاده از این قلاب مدیریت می شود.
-
بازیابی آسان: اگر نیاز به واکشی مجدد داده ها داشته باشیم (مثلاً پس از به روز رسانی)، می توانیم به سادگی تماس بگیریم
refetchCars()
.
نتیجه
با استفاده از Zustand برای مدیریت ایالت، Tanstack Query برای واکشی داده ها، و ایجاد یک سیستم اعلان نان تست متمرکز، فرآیند واکشی داده های خود را به طور قابل توجهی ساده کرده ایم. این رویکرد به ما اجازه می دهد تا وظایف پیچیده مدیریت داده را با یک خط کد در اجزای خود انجام دهیم که منجر به برنامه های React تمیزتر و قابل نگهداری تر می شود.
به یاد داشته باشید، کلید این ساده سازی، انتقال پیچیدگی به قلاب هایی با طراحی خوب و قابل استفاده مجدد و استفاده از کتابخانه های قدرتمندی مانند Zustand و Tanstack Query است. به این ترتیب، ما یک بار مشکل را حل می کنیم و از راه حل در کل برنامه خود بهره مند می شویم.