Tại sao nên sử dụng React-query trong dự án React?

7 min read

React-query, được phát triển bởi TanStack, là một thư viện giúp đơn giản hóa việc fetching data và quản lý state trong các ứng dụng React. Trong bài viết này, bạn sẽ được giới thiệu về react-query, các tính năng chính của nó và cách bạn có thể bắt đầu với nó trong các dự án React của mình.

React-query là gì?

React-query là một thư viện Javascript nhằm đơn giản hóa tác vụ phức tạp là fetching và store dữ liệu trong các ứng dụng React. Bạn có thể dễ dàng quản lý data từ nhiều nguồn khác nhau, bao gồm API REST, GraphQL hoặc thậm chí state bằng một bộ hook và tiện ích được cung cấp bởi react-query.

Các tính năng chính

Data Fetching: React-query hỗ trợ cách tiếp cận khai báo để trích xuất dữ liệu. Bằng cách sử dụng các hook như useQuery và useMutation, bạn có thể xác định các query và mutation. Điều này sẽ dẫn đến việc code đơn giản hơn, có tổ chức hơn.

Automatic Caching: Cache lưu trữ kết quả query là một phần của React-query. Nếu mutation xảy ra, nó sẽ tự động cập nhật dữ liệu để đảm bảo giao diện của bạn tiếp tục nhất quán.

Background Data Sync: Nó có thể tự động tải lại dữ liệu ở background, giữ cho dữ liệu của bạn luôn mới mà không cần can thiệp thủ công.

Pagination and Infinite Scrolling: React-query cung cấp các hook để xử lý pagination và infinite scrolling một cách dễ dàng.

Optimistic Updates: Bạn có thể triển khai các bản cập nhật lạc quan một cách dễ dàng, giúp ứng dụng của bạn phản hồi nhanh hơn.

Set up react-query trong dự án React

Tôi sẽ focus vào một ví dụ cơ bản để xem việc bắt đầu với React-query đơn giản như thế nào. Điều đầu tiên bạn cần làm là cài đặt thư viện @tanstack/react-query.

npm install @tanstack/react-query
// or
yarn add @tanstack/react-query

Sau khi thư viện được cài đặt trong ứng dụng của chúng ta, hãy tạo provider và client để sử dụng React-query. Bạn có thể tạo nó trong file index.tsx trong thư mục src.

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);

const queryClient = new QueryClient();

root.render
  <QueryClientProvider client={queryClient}>
    <App />
  </QueryClientProvider>
);

Sau đó, bạn có thể sử dụng React-query Hooks. Tôi sẽ sử dụng trong file App.tsx.

Giả sử chúng ta có một hàm fetching sử dụng fetch để lấy dữ liệu users.

async function fetchingUsers() {
	return fetch('https://jsonplaceholder.typicode.com/users').then(response => response.json());
}

Kết hợp với hook useQuery của React-Query, thì fetching data sẽ vô cùng đơn giản.

import React from "react";
import logo from "./logo.svg";
import "./App.css";
import { useQuery } from "@tanstack/react-query";

async function fetchingUsers() {
  return fetch("https://jsonplaceholder.typicode.com/users").then((response) =>
    response.json(),
  );
}

function App() {
  const userData = useQuery(["users"], fetchingUsers, {
    enabled: false,
  });

  return (
    <div>
      <div>
        <button onClick={() => userData.refetch()}>Get Users</button>
        <div>
          {userData.isFetching && <div>Fetching user data...</div>}
          {userData.isError && <div>{`Error get data!!!`}</div>}
          {userData.data &&
            userData.data.length > 0 &&
            userData.data.map((user: any) => <div>{user.name}</div>)}
        </div>
      </div>
    </div>
  );
}

export default App;

Trong ví dụ trên, tôi sử dụng useQuery để fetching user list. React-query xử lý fetching state, xử lý lỗi và lưu vào cache ở phía background.

get-users-using-react-query

Ta sẽ fetching data từ API khi nhấn nút Get Users. Quá trình fetching không thấy được rõ do lượng dữ liệu thấp vì quá nhanh.

Ngoài useQuery, chúng tôi còn có useMutation, trong đó hook này gần giống như useQuery nhưng được sử dụng để thay đổi dữ liệu. Tôi đưa ra một ví dụ về việc sử dụng nó.

import React from "react";
import logo from "./logo.svg";
import "./App.css";
import { useQuery, useMutation } from "@tanstack/react-query";

const fetchingUsers = () => {
  return fetch("https://jsonplaceholder.typicode.com/users").then((response) =>
    response.json(),
  );
};

const updateUser = (newPost: any) => {
  return fetch("https://jsonplaceholder.typicode.com/posts", {
    method: "POST",
    body: JSON.stringify(newPost),
    headers: {
      "Content-type": "application/json; charset=UTF-8",
    },
  }).then((response) => response.json());
};

function App() {
  const userData = useQuery(["users"], fetchingUsers, {
    enabled: false,
  });

  const mutatePost = useMutation(["posts"], updateUser);

  return (
    <div>
      <div>
        <button onClick={() => userData.refetch()}>Get Users</button>
        <div>
          {userData.isFetching && <div>Fetching user data...</div>}
          {userData.isError && <div>{`Error get data!!!`}</div>}
          {userData.data &&
            userData.data.length > 0 &&
            userData.data.map((user: any) => <div>{user.name}</div>)}
        </div>
      </div>
      <hr />
      <div>
        <button
          onClick={() =>
            mutatePost.mutate({
              title: "First Post",
              body: "First Post Body",
              userId: 1,
            })
          }
        >
          Add New Post
        </button>
        <div>
          {mutatePost.isLoading && <div>Adding new post...</div>}
          {mutatePost.isError && <div>{`Error add new post!!!`}</div>}
          {mutatePost.data && (
            <div>{`Success add new post with title : '${mutatePost.data.title}'`}</div>
          )}
        </div>
      </div>
    </div>
  );
}

export default App;

Điểm khác nhau giữa useQuery và useMutation

Mục đích: useQuery sử dụng cho fetching dữ liệu, còn useMutation sử dụng cho chỉnh sửa dữ liệu.

Trường hợp sử dụng:  useQuery được sử dụnng khi bạn muốn fetch and display dữ liệu, còn useMutation được sử dụng khi bạn muốn thay đổi những dữ liệu đó.

Dữ liệu trả về: useQuery returns { data, error, isLoading, isFetching }, còn useMutation returns { mutate, data, error, isError, isLoading, isSuccess }.

Xử lý lỗi: Cả hai hook đều xử lý lỗi, nhưng useMutation cung cấp các tính năng bổ sung để xử lý các cập nhật và khôi phục lạc quan trong trường hợp có lỗi trong quá trình mutation.

Tại sao nên dùng react-query?

Sử dụng React-query mang lại nhiều lợi ích cho các ứng dụng React, đặc biệt là trong việc quản lý và xử lý dữ liệu từ server. Dưới đây là một số lý do chính:

  1. Quản lý trạng thái dữ liệu đơn giản và hiệu quả: React-query cung cấp các công cụ mạnh mẽ để quản lý trạng thái của dữ liệu từ server. Nó giúp bạn dễ dàng lấy dữ liệu, cập nhật dữ liệu, và theo dõi trạng thái của các yêu cầu dữ liệu (như loading, error, success).
  2. Tự động hoá quá trình fetching và caching: React-query tự động xử lý việc caching dữ liệu và đảm bảo rằng dữ liệu không bị fetch lại nếu đã có trong cache, giúp giảm tải cho server và cải thiện hiệu suất của ứng dụng.
  3. Cải thiện trải nghiệm người dùng với stale-while-revalidate: React-query hỗ trợ cơ chế stale-while-revalidate, cho phép hiển thị dữ liệu cũ từ cache trong khi dữ liệu mới đang được tải về. Điều này giúp giảm thiểu thời gian chờ đợi và mang lại trải nghiệm mượt mà hơn cho người dùng.
  4. Xử lý các thao tác đồng bộ dữ liệu dễ dàng: React-query cung cấp các công cụ để xử lý các thao tác đồng bộ dữ liệu như refetching, polling, và tự động cập nhật dữ liệu khi mạng trở lại (offline-first).
  5. Quản lý các hiệu ứng phụ phức tạp: Với React-query, bạn có thể dễ dàng quản lý các hiệu ứng phụ phức tạp liên quan đến việc fetching dữ liệu, như retry khi gặp lỗi, phân trang (pagination), và vô hiệu hóa bộ nhớ cache (invalidation).
  6. Tích hợp tốt với các thư viện khác: React-query có thể dễ dàng tích hợp với các thư viện khác trong hệ sinh thái React như Axios, Fetch API, và thậm chí là GraphQL, giúp bạn linh hoạt trong việc lựa chọn công cụ phù hợp cho dự án của mình.
  7. Cộng đồng và tài liệu phong phú: React-queryQuery có một cộng đồng lớn và tài liệu phong phú, cung cấp nhiều ví dụ và hướng dẫn giúp bạn nhanh chóng nắm bắt và sử dụng thư viện một cách hiệu quả.

Tóm lại, sử dụng React-query giúp bạn đơn giản hóa việc quản lý dữ liệu từ server, tăng hiệu suất và cải thiện trải nghiệm người dùng trong các ứng dụng React.

Tổng kết

React-query giúp việc fetching và sync dữ liệu trở nên dễ dàng hơn bao giờ hết. Tính đơn giản và mạnh mẽ của React-query sẽ giúp bạn manage dữ liệu một cách hiệu quả, cho dù bạn đang xây dựng một ứng dụng nhỏ hay một dự án mở rộng.

Với React-query, bạn có thể tập trung phát triển các tính năng của ứng dụng và cung cấp trải nghiệm người dùng tốt hơn đồng thời dễ dàng hơn trong việc quản lý dữ liệu. Hãy dùng thử nó trong dự án React tiếp theo và có thể bạn sẽ tự hỏi làm thế nào bạn có thể quản lý dữ liệu mà không có nó.

Avatar photo

Leave a Reply

Your email address will not be published. Required fields are marked *