Giới Thiệu Về React Query
Trong quá trình tìm kiếm thông tin trên một số trang tuyển dụng, mình nhận thấy rằng có rất nhiều nhà tuyển dụng yêu cầu kinh nghiệm về thư viện React Query. Theo số liệu từ npmjs và GitHub, React Query đã đạt được 1,466,787 lượt tải hàng tuần và 41.9k sao vào thời điểm mình viết bài. Vậy chúng ta hãy cùng khám phá những kiến thức cơ bản về package đang rất hot này nhé! 😘
React Query Là Gì?
React Query là một thư viện dành cho React, giúp bạn thực hiện việc fetching, caching, đồng bộ và cập nhật dữ liệu sau khi lấy từ cơ sở dữ liệu. Nó có thể được hiểu như một hệ thống caching mini trên local.
React Query Có Thể Làm Gì?
Để thấy rõ sự tiện ích mà React Query mang lại, chúng ta hãy so sánh đoạn code khi không sử dụng và khi sử dụng React Query để fetch dữ liệu.
Trường Hợp Không Sử Dụng React Query
Dưới đây là một ví dụ về việc fetching dữ liệu thông thường bằng useEffect và ba state để lưu trạng thái của fetch: loading, error và data.
javascript
import React, { useState, useEffect } from 'react';
import axios from '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>Ví dụ React Query với Star Wars API</h1>
{isError && <div>Có lỗi xảy ra ...</div>}
{isLoading ? (
<div>Đang tải ...</div>
) : (
<pre>{JSON.stringify(data, null, 2)}</pre>
)}
</div>
);
}
export default App;
Trường Hợp Sử Dụng React Query
Dưới đây là đoạn code khi sử dụng React Query để fetch dữ liệu.
javascript
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>Ví dụ React Query với Star Wars API</h1>
{error && <div>Có lỗi xảy ra ...</div>}
{isLoading ? (
<div>Đang lấy thông tin của Luke Skywalker ...</div>
) : (
<pre>{JSON.stringify(data, null, 2)}</pre>
)}
</div>
);
}
export default App;
Khi fetch xong, dữ liệu đã được cache qua key 'posts'. Như vậy, React Query sẽ tự động xử lý việc loading, error và data.
Truy Cập Dữ Liệu Cache Tại Component Khác
Một điểm tiện lợi nữa của React Query là bạn có thể dễ dàng truy cập dữ liệu đã cache từ bất kỳ component nào mà không cần sử dụng Redux hay truyền qua props. Dưới đây là cách truy cập dữ liệu đã cache.
javascript
import { useQuery } from '@tanstack/react-query';
function CachedPosts() {
const { data, isLoading, error } = useQuery(['posts']);
if (isLoading) return <p>Đang tải các bài viết đã cache...</p>;
if (error) return <p>Có lỗi xảy ra khi tải các bài viết đã cache.</p>;
return (
<div>
<h2>Các Bài Viết Đã Cache:</h2>
{data.map(post => (
<div key={post.id}>{post.title}</div>
))}
</div>
);
}
export default CachedPosts;
Thêm Hoặc Chỉnh Sửa Dữ Liệu Cache Đơn Giản
React Query cho phép bạn thêm hoặc chỉnh sửa dữ liệu cache một cách dễ dàng và ngắn gọn như sau:
javascript
import { useQueryClient } from 'react-query';
const Component = () => {
const queryClient = useQueryClient();
const addOrUpdateData = () => {
queryClient.setQueryData(['todos'], (oldData) => {
return [...(oldData || []), { id: 4, title: 'New Todo' }];
});
};
return <button onClick={addOrUpdateData}>Thêm/Cập nhật Todo</button>;
};
Sử Dụng useMutation
React Query đã thiết kế useMutation để thực hiện các hành động thay đổi dữ liệu như thêm, chỉnh sửa hoặc xoá. Dưới đây là một ví dụ về việc sử dụng hàm useMutation:
javascript
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 ? 'Đang tạo bài viết...' : 'Tạo Bài Viết'}
</button>
{mutation.isError && <p>Có lỗi xảy ra khi tạo bài viết.</p>}
{mutation.isSuccess && <p>Bài viết đã được tạo thành công!</p>}
</div>
);
}
export default CreatePost;
Kết Luận
Ưu Điểm:
- Giúp mã nguồn trở nên sạch sẽ, giảm thiểu việc phải khai báo nhiều state và thay thế một phần code dài dòng của Redux.
- Hỗ trợ tốt cho việc fetching data, tiết kiệm thời gian cho developer.
- Rất hữu ích cho các ứng dụng muốn tối ưu hóa việc làm việc với server data.
Nhược Điểm:
- Cần quản lý tốt việc caching dữ liệu, nếu không sẽ gây nên những vấn đề mới cho các tester.
- Việc sử dụng đồng thời Redux và React Query có thể gây ra sự rối rắm trong luồng code.
Lời Kết:
Trong một môi trường CNTT có tốc độ thay đổi nhanh chóng, việc cập nhật công nghệ là vô cùng quan trọng. React Query là một thư viện đáng để bạn tìm hiểu và áp dụng. Trước khi đưa vào dự án, hãy đảm bảo rằng bạn đã trao đổi kỹ với tech lead và các thành viên trong nhóm để mọi người đều nắm rõ nhé. Nếu có điều gì sai sót trong bài viết, mong các bạn góp ý để cùng nhau thảo luận.
source: viblo