React Query یکی از کتابخونه های محبوب برای مدیریت state و داده‌ها در برنامه‌های React است که به طور خاص برای مدیریت درخواست‌های سمت سرور (Server State) طراحی شده است. این کتابخونه فرآیندهای پیچیده‌ای مثل گرفتن داده‌ها (fetch)، کش کردن (cache)، به‌روزرسانی (sync)، و مدیریت خطا را ساده می‌کند.

React Query قابلیت‌هایی مثل کش کردن خودکار داده‌ها، مدیریت به‌روزرسانی داده‌ها، و همچنین re-fetch خودکار را فراهم می‌کند. این باعث می‌شود که نیازی به مدیریت دستی state برای داده‌های سرور نداشته باشید.

آموزش React – مبتدی تا پیشرفته

ویژگی‌های کلیدی React Query:

کشینگ خودکار: داده‌ها را برای مدتی کش می‌کند تا درخواست‌های اضافی به سرور کاهش یابد.

Refetching خودکار: پس از تغییر focus صفحه، یا در زمان مشخصی داده‌ها را دوباره از سرور می‌گیرد.

مدیریت خطا: مدیریت ساده برای خطاهای درخواست.

هماهنگی با سرور: به‌روزرسانی داده‌ها پس از mutation به صورت خودکار هماهنگ می‌شود.

سازگار با SSR/ISR: مناسب برای پروژه‌های Next.js.

نصب:

برای استفاده از React Query، ابتدا آن را نصب کنید:

npm install @tanstack/react-query

مثال عملی:

فرض کنید می‌خواهید لیستی از کاربران را از یک API بگیرید و در صفحه نمایش دهید:

راه‌اندازی Query Client:

در فایل اصلی پروژه (مثلاً index.js یا App.jsQueryClientProvider را wrap کنید:

import React from "react";
import ReactDOM from "react-dom";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import App from "./App";

const queryClient = new QueryClient();

ReactDOM.render(
  <QueryClientProvider client={queryClient}>
    <App />
  </QueryClientProvider>,
  document.getElementById("root")
);

ساخت یک Query برای دریافت داده‌ها:

در فایل مربوط به کامپوننت خود، از useQuery برای گرفتن داده‌ها استفاده کنید:

import React from "react";
import { useQuery } from "@tanstack/react-query";

const fetchUsers = async () => {
  const response = await fetch("https://jsonplaceholder.typicode.com/users");
  if (!response.ok) {
    throw new Error("Error fetching users");
  }
  return response.json();
};

const UserList = () => {
  const { data, isLoading, error } = useQuery(["users"], fetchUsers);

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

  return (
    <div>
      <h1>User List</h1>
      <ul>
        {data.map((user) => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
};

export default UserList;

توضیحات کد:

useQuery:

["users"]: کلید یکتای query (cache key).

fetchUsers: فانکشن برای گرفتن داده‌ها از API.

isLoading: نشان‌دهنده وضعیت لودینگ.

error: مدیریت خطا.

data: داده‌های دریافت شده از API.

افزودن Mutation (برای افزودن داده‌ها):

برای مدیریت تغییرات داده‌ها مثل افزودن یا حذف یک کاربر، می‌توانید از useMutation استفاده کنید:

import React, { useState } from "react";
import { useMutation, useQueryClient } from "@tanstack/react-query";

const addUser = async (newUser) => {
  const response = await fetch("https://jsonplaceholder.typicode.com/users", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(newUser),
  });
  if (!response.ok) {
    throw new Error("Error adding user");
  }
  return response.json();
};

const AddUser = () => {
  const queryClient = useQueryClient();
  const mutation = useMutation(addUser, {
    onSuccess: () => {
      queryClient.invalidateQueries(["users"]); // Refetch users list
    },
  });

  const [name, setName] = useState("");

  const handleSubmit = () => {
    mutation.mutate({ name });
    setName("");
  };

  return (
    <div>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Enter user name"
      />
      <button onClick={handleSubmit}>Add User</button>
    </div>
  );
};

export default AddUser;

مزایا در پروژه‌های واقعی:

ساده‌تر کردن مدیریت state سرور.

افزایش کارایی با کشینگ خودکار.

قابلیت هماهنگی آسان بین داده‌های سرور و کلاینت.

مدیریت ساده‌تر درخواست‌ها در پروژه‌های SPA و SSR.