+1

React Query - Stack chất lượng với Frontend DEV

image.png Lướt qua 1 số trang tuyển dụng thì mình có đọc được 1 số thông tin tuyển dụng yêu cầu kinh nghiệm về react-query.

Xem thông tin trên npmjs và github thì con số rất ấn tượng với 1,466,787 lượt tải hàng tuần + 41.9k stars vào thời điểm mình viết bài. Vậy hãy cùng tìm hiểu những kiến thức cơ bản về package so hot này nhé. 😘😘

React Query là gì

React-query là 1 thư viện data-fetching dành cho react. Nó có thể fetching, caching, đồng bộ và update data sau khi lấy từ database. Bạn có thể hiểu nó như 1 hệ thống caching mini bên dưới local vậy.

React Query có thể làm gì

Hãy cùng so sánh 1 đoạn code có và không có react-query để thấy được sự khác nhau nhé

Case không sử dụng react-query trong fetching data

Dưới đây là 1 ví dụ về việc fetching data thông thường. Ta sẽ sử dụng useEffect và 3 state nữa để lưu trạng thái của fetch. Bao gồm loading, error, data.

import React, {useState, useEffect} from 'react';
import axios from 'axios';
// regular fetch with axios
function App() {
  const [isLoading, setLoading] = useState(false)
  const [isError, setError] = useState(false)
  const [data, setData] = useState({});
 
  useEffect(() => {
    const fetchData = async () => {
      setError(false);
      setLoading(true);
  
      try {
        const response = await axios('http://swapi.dev/api/people/1/');
  
        setData(response.data);
      } catch (error) {
        setError(true);
      }
      setLoading(false);
    };
    fetchData()
  }, []);
return (
    <div className="App">
      <h1>React Query example with Star Wars API</h1>
      {isError && <div>Something went wrong ...</div>}
 
      {isLoading ? (
        <div>Loading ...</div>
      ) : (
        <pre>{JSON.stringify(data, null, 2)}
        </pre>
      )}
    </div>
  );
}
export default App;

Case sử dụng react-query để fetch data

import React from 'react';
import axios from 'axios';
import {useQuery} from 'react-query';

function App() {
  const { isLoading, error, data } = useQuery('posts', () =>
  axios('http://swapi.dev/api/people/1/'))
return (
    <div className="App">
      <h1>React Query example with star wars API</h1>
      {error && <div>Something went wrong ...</div>}
 
      {isLoading ? (
        <div>Retrieving Luke Skywalker Information ...</div>
      ) : (
        <pre>{JSON.stringify(data, null, 2)}
        </pre>
      )}
    </div>
  );
}
export default App;

Sau khi fetch thì data đã được cache qua key posts. Và ae có thể thấy được react-query hỗ trợ luôn việc xử lý loading, error, data.

Access cache data ở 1 component khác

Rất tiện phải không. Thay vì sử dụng redux hay truyền qua props, ae có thể access luôn data đã cache bằng react-query. Ae để ý tham số posts khi fetch data khi muốn access nó.

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

function CachedPosts() {
  const { data, isLoading, error } = useQuery(['posts']);

  if (isLoading) return <p>Loading cached posts...</p>;
  if (error) return <p>Error loading cached posts.</p>;

  return (
    <div>
      <h2>Cached Posts:</h2>
      {data.map(post => (
        <div key={post.id}>{post.title}</div>
      ))}
    </div>
  );
}

export default CachedPosts;

Add or edit data cache đơn giản và ngắn gọn

import { useQueryClient } from 'react-query';

const Component = () => {
  const queryClient = useQueryClient();

  const addOrUpdateData = () => {
    // Example of updating cache for a query with key 'todos'
    queryClient.setQueryData(['todos'], (oldData) => {
      return [...(oldData || []), { id: 4, title: 'New Todo' }];
    });
  };

  return <button onClick={addOrUpdateData}>Add/Update Todo</button>;
};

useMutation

React query đã thiết kế useQuery để sử dụng fetdata. Và useMutaion để thực điện các action thay đổi data như add, edit, delete. Và đây là 1 ví dụ về 1 case sử dụng.

import { useMutation, useQueryClient } from '@tanstack/react-query';
import axios from 'axios';

const createPost = async (newPost) => {
  const { data } = await axios.post('/api/posts', newPost);
  return data;
};

function CreatePost() {
  const queryClient = useQueryClient();

  const mutation = useMutation(createPost, {
    onMutate: async (newPost) => {
      await queryClient.cancelQueries('posts');
      
      const previousPosts = queryClient.getQueryData('posts');
      queryClient.setQueryData('posts', (old) => [...old, newPost]);

      return { previousPosts };
    },
    
    onError: (err, newPost, context) => {
      queryClient.setQueryData('posts', context.previousPosts);
    },

    onSuccess: () => {
      queryClient.invalidateQueries('posts');
    },

    onSettled: () => {
      queryClient.invalidateQueries('posts');
    },
  });

  const handleCreatePost = () => {
    mutation.mutate({ title: 'New Post', content: 'This is a new post' });
  };

  return (
    <div>
      <button onClick={handleCreatePost} disabled={mutation.isLoading}>
        {mutation.isLoading ? 'Creating Post...' : 'Create Post'}
      </button>
      {mutation.isError && <p>Error creating post.</p>}
      {mutation.isSuccess && <p>Post created successfully!</p>}
    </div>
  );
}

export default CreatePost;
  • queryClient.removeQueries(['todos']); : sử dụng để remove data cache
  • queryClient.invalidateQueries(['todos']);: Như 1 flag để biết rằng data todos này đã cũ. Lần fetch tiếp theo sẽ call lại api
  • queryClient.prefetchQuery(['todos'], fetchTodos); Hoặc bạn cần call luôn api
  • @tanstack/react-query-devtools : là 1 tool để bạn có thể view được data đã cache

Tổng kết:

Ưu điểm:

  • Clearn code, hạn chế phải khai báo nhiều state và thay thể 1 phần code dài dòng của redux
  • Hỗ trợ tốt, tiết kiệm thời gian cho dev về fetch data và tương tác với server data
  • Hữu ích cho các ứng dụng muốn tối ưu mạnh ở client về fetching data và tương tác với server data

Nhược điểm:

  • FE cần quản lý tốt tầng data cache này không thì sẽ là 1 luồng bug mới dành cho tester
  • Việc sử dụng đan xen redux và react-query có thể sẽ gây rối cho luồng code chung

End:

  • Trong 1 môi trường IT đào thải nhanh chóng thì việc update tech là việc hết sức quan trọng. Và React query xứng đáng để bạn tìm hiểu nó
  • Trước khi áp dụng vào dự án ae nên trao đổi kỹ với techlead và member trong team để mn cùng nắm đc nhé
  • Bài viết có gì sai sót mong ae comment cùng thảo luận nhé

All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.