در برنامه های کاربردی وب مدرن، مدیریت واکشی داده ها و مدیریت استیت به طور موثر برای ساخت برنامه های کاربردی مقیاس پذیر و قابل نگهداری بسیار مهم است. Redux Toolkit Queries (RTK Queries) یک راه حل قدرتمند است که این کارها را ساده می کند و مجموعه ای از ابزارها را برای کارآمدتر کردن فرآیند توسعه شما ارائه می دهد. در این مقاله، ویژگیهای اصلی RTK Queries را بررسی میکنیم، نحوه ایجاد endpoint ها و استفاده از هوک های تولید شده خودکار را یاد میگیریم.
اعتقاد بر این است که React و Redux بهترین ترکیب برای مدیریت استیت در برنامه های React در مقیاس بزرگ هستند.
با این حال، با گذشت زمان، محبوبیت Redux به دلیل پیچیدگی در پیکربندی یک فروشگاه Redux کاهش یافت. همچنین این واقعیت که Redux به کد boilerplate بیش از حد نیاز دارد. Redux Tool Kit این مشکلات را حل می کند. برخی از گزینهها را برای پیکربندی استور گلوبال ارائه میکند و با انتزاع API Redux تا حد امکان، هم اکشن ها و هم reducer ها را سادهتر میسازد.
RTK Query چیست؟
RTK Query یک راه حل قدرتمند ذخیره اطلاعات سرور است که به صراحت برای Redux Toolkit ساخته شده است. این بر روی Redux Tool Kit ساخته شده است و از Redux به صورت داخلی برای معماری خود استفاده می کند. RTK Query از بسیاری از کتابخانه های عالی دیگر مانند React Query و Apollo الهام گرفته است.
RTK Query را می توان با هر چارچوبی که قادر به استفاده از Redux باشد (Vue.js، Svelte، Angular و غیره) ادغام کرد. با TypeScript ساخته شده است و از OpenAPI و GraphQL پشتیبانی می کند. همچنین از React Hooks پشتیبانی می کند.
RTK Query به شما امکان می دهد تاریخچه تغییرات استیت را در طول زمان پیگیری کنید. اندازه بسته بسیار کوچک و RTK Query از کوئری ها و جهش ها برای بهبود واکشی و ذخیره سازی داده ها استفاده می کند. و دارای پشتیبانی داخلی برای رسیدگی به خطا و به روز رسانی های optimistic ارائه می دهد.
Queries - این رایج ترین مورد استفاده برای RTK Query است. شما می توانید از عملیات کوئری با هر کتابخانه واکشی داده ای که انتخاب می کنید استفاده کنید.
Mutations - یک جهش (Mutations) برای ارسال بهروزرسانیها به سرور و تکرار آن در حافظه پنهان محلی استفاده میشود.
TRPC چیست؟ و چرا باید از آن استفاده کرد؟
چه زمانی باید از RTK Query استفاده کنید؟
به طور کلی، دلایل اصلی استفاده از RTK Query عبارتند از:
شما در حال حاضر یک برنامه Redux دارید و می خواهید منطق واکشی داده های موجود خود را ساده کنید
میخواهید بتوانید از Redux DevTools برای مشاهده تاریخچه تغییرات استیت خود در طول زمان استفاده کنید
شما می خواهید بتوانید رفتار RTK Query را با بقیه اکوسیستم Redux ادغام کنید
منطق برنامه شما باید خارج از React کار کند
ویژگی های کلیدی RTK Query
- کش خودکار
- همگام سازی پس زمینه
- تلاش مجدد خودکار
- pagination و بارگذاری بیشتر
- یکپارچه سازی میدلور
RTK Query چه چیزی را شامل می شود؟
کیت ابزار Redux با چندین پکیج مفید مانند Immer، Redux-Thunk و Reselect همراه است. این باعث راحت تر شدن توسعه دهندگان React می شود و به آنها اجازه میدهد تا استیت را مستقیماً تغییر دهند (عدم تغییرپذیری دسته Immer) و از میدلور هایی مانند Thunk (که اکشن های async را مدیریت میکند) استفاده کنند. همچنین از Reselect، یک کتابخانه ساده «selector» برای Redux، برای ساده کردن فانکشن های ریدیوسر استفاده می کند.
چرا از React Toolkit Query استفاده کنیم؟
واکشی داده ها از سرور برای نمایش، کاری عادی است. به روز رسانی داده ها، ارسال داده های به روز شده به سرور، و نگهداری داده های ذخیره شده در کش روی کلاینت نیز مورد نیاز است. در حالی که همه این موارد پیچیده هستند، RTK توسعه آن را آسانتر میکند و در عین حال سایر رفتارهای مورد نیاز در برنامه امروزی را اضافه میکند:
ردیابی استیت بارگیری برای نشان دادن اسپینرهای رابط کاربری
اجتناب از درخواست های تکراری برای همان داده ها
مدیریت طول عمر کش هنگام تعامل کاربر با رابط کاربری
برای آشنایی با SSR و CSR و .. این مقاله را بررسی کنید.
ویژگی های اصلی Redux Tool Kit API چیست؟
تابع API توسط Redux Took Kit استفاده می شود، آنها چکیده ای از تابع Redux API موجود هستند و به ساده کردن جریان Redux به شیوه ای خوانا و قابل مدیریت کمک می کنند.
configureStore:
یک نمونه استور Redux مانند createStore
اصلی از Redux ایجاد می کند، اما یک آبجکت گزینه با نام را می پذیرد و افزونه Redux DevTools را به طور خودکار تنظیم می کند.
createAction:
رشته ای از نوع اکشن را می پذیرد و یک تابع ایجاد کننده اکشن را که از آن نوع استفاده می کند، برمی گرداند.
createReducer:
یک مقدار استیت اولیه و یک جدول جستجو از انواع توابع را برای توابع ریدیوسر می پذیرد و یک ریدیوسر ایجاد می کند که تمام انواع توابع را کنترل می کند.
createSlice:
یک استیت اولیه و یک جدول جستجو با نامها و توابع ریدیوسر را میپذیرد و به طور خودکار توابع ایجادکننده اکشن، رشتههای نوع اکشن و یک ریدیوسر را تولید میکند.
کد boilerplate در Redux را می توان با استفاده از createSlice
ساده تر کرد، که به طور خودکار توابع ایجاد کننده اکشن و ریدیوسر را تولید می کند.
createSlice چیست؟
این یک تابع کمکی است که یک Slice از استور را تولید می کند. نام اسلایس، استیت اولیه و تابع ریدیسور را برای برگرداندن ریدیوسر، انواع اکشن و سازندگان اقدام می گیرد.
همه اکشن ها و ریدیوسر ها در یک مکان ساده هستند که در آن یک برنامه redux سنتی باید هر اکشن و تابع مربوط به آن را در داخل ریدیوسر مدیریت کنیم. هنگام استفاده از createSlice، نیازی به استفاده از سوئیچ برای شناسایی اکشن نیست.
از آنجایی که جعبه ابزار Redux از Immer استفاده می کند، لازم نیست نگران تغییر استیت باشیم. از آنجایی که یک اسلایس، اکشنها و ریدیسور ها را ایجاد میکند، میتوانیم آنها را export کنیم و از آنها در کامپوننت خود و در Store برای پیکربندی Redux استفاده کنیم، بدون اینکه فایلها و دایرکتوریهای جداگانه برای اکشنها و ریدیسور ها داشته باشیم.
این استور می تواند مستقیماً از کامپوننت از طریق APIهای redux با استفاده از useSelector
و useDispatch
استفاده شود.
نحوه استفاده از RTK Query در ری اکت
ابتدا پکیج npm install @reduxjs/toolkit react-redux
را نصب کنید.
سپس نقطه پایانی ایجاد کنید.
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
const usersApi = createApi({
baseQuery: fetchBaseQuery({ baseUrl: "/users" }),
endpoints: (builder) => ({
fetchUser: builder.query({
query: (id) => `user/${id}`,
}),
createUser: builder.mutation({
query: (user) => ({
url: "user",
method: "POST",
body: user,
}),
}),
}),
});
export const { useFetchUserQuery, useCreateUserMutation } = usersApi;
2. سرویس را به استور خود اضافه کنید.
import { configureStore } from '@reduxjs/toolkit'
// Or from '@reduxjs/toolkit/query/react'
import { setupListeners } from '@reduxjs/toolkit/query'
import { usersApi } from './services/usersApi'
export const store = configureStore({
reducer: {
// Add the generated reducer as a specific top-level slice
[usersApi.reducerPath]: usersApi.reducer,
},
// Adding the api middleware enables caching, invalidation, polling,
// and other useful features of `rtk-query`.
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(usersApi.middleware),
})
// optional, but required for refetchOnFocus/refetchOnReconnect behaviors
// see `setupListeners` docs - takes an optional callback as the 2nd arg for customization
setupListeners(store.dispatch)
معماری میکروفرانت اند در ری اکت
معماری میکروفرانت اند در Next.js
3. اپ را داخل Provider
قرار دهید.
import * as React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import App from './App'
import { store } from './app/store'
const rootElement = document.getElementById('root')
render(
<Provider store={store}>
<App />
</Provider>,
rootElement
)
نحوه استفاده با هوک :
import React from "react";
import { useFetchUserQuery, useCreateUserMutation } from "./usersApi";
const UserProfile = ({ userId }) => {
const { data, error, isLoading } = useFetchUserQuery(userId);
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<h1>{data.name}</h1>
<p>Email: {data.email}</p>
</div>
);
};
const CreateUserForm = () => {
const [createUser, { isLoading }] = useCreateUserMutation();
const handleSubmit = async (user) => {
try {
await createUser(user).unwrap();
alert("User created successfully!");
} catch (error) {
alert(`Error: ${error.message}`);
}
};
// Render form components and handle form submission with handleSubmit
};
نحوه استفاده از کال های مستقیم بدون هوک :
import { usersApi } from "./usersApi";
const fetchUserById = async (id) => {
try {
const result = await usersApi.endpoints.fetchUser.initiate(id).unwrap();
console.log("User data:", result);
} catch (error) {
console.error("Error fetching user:", error);
}
};
fetchUserById(1);
نحوه استفاده از به روز رسانی کش دستی :
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'
const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: '/',
}),
tagTypes: ['Post'],
endpoints: (build) => ({
getPost: build.query({
query: (id) => `post/${id}`,
providesTags: ['Post'],
}),
updatePost: build.mutation({
query: ({ id, ...patch }) => ({
url: `post/${id}`,
method: 'PATCH',
body: patch,
}),
async onQueryStarted({ id, ...patch }, { dispatch, queryFulfilled }) {
const patchResult = dispatch(
api.util.updateQueryData('getPost', id, (draft) => {
Object.assign(draft, patch)
})
)
try {
await queryFulfilled
} catch {
patchResult.undo()
/**
* Alternatively, on failure you can invalidate the corresponding cache tags
* to trigger a re-fetch:
* dispatch(api.util.invalidateTags(['Post']))
*/
}
},
}),
}),
})
استفاده از polling
:
import * as React from 'react'
import { useGetPokemonByNameQuery } from './services/pokemon'
export const Pokemon = ({ name }: { name: string }) => {
// Automatically refetch every 3s
const { data, status, error, refetch } = useGetPokemonByNameQuery(name, {
pollingInterval: 3000,
})
return <div>{data}</div>
}
برای آشنایی با تفاوت های بین ری اکت 19 و ری اکت 18 این مقاله را از دست ندهید. همچنین برای آشنایی با تزریق وابستگی در ری اکت نیز این مقاله را بررسی کنید.
نتیجه
Redux Toolkit Queries یک رویکرد قوی و سازگار برای بهبود واکشی، ذخیرهسازی و مدیریت استیت برنامههای React شما ارائه میدهد. با تسلط بر ایجاد نقاط پایانی، استفاده از هوک های تولید شده خودکار، و استفاده از کال های مستقیم بدون پین، میتوانید تمام قابلیتهای RTK Queries را باز کنید و برنامههای مقیاسپذیر و قابل نگهداری بیشتری بسازید.