Quản lý trạng thái trong React: Redux Toolkit và React Query
16 tháng 6, 2026
Giới thiệu
Trong thế giới phát triển front-end hiện đại, việc quản lý trạng thái ứng dụng trở thành thách thức khi dự án phát triển tăng trưởng. Các thư viện như Redux Toolkit và React Query đã cho chúng ta những giải pháp mạnh mẽ nhưng thường được sử dụng riêng lẻ. Bài viết này sẽ hướng dẫn cách kết hợp hai công cụ này để tận dụng ưu điểm của từng thư viện: Redux Toolkit cho trạng thái đồng bộ, dữ liệu toàn cục và React Query cho fetch dữ liệu bất đồng bộ, caching, và refetch.
Redux Toolkit – Tóm tắt
Redux Toolkit (RTK) được thiết kế để làm giảm boilerplate trong Redux. Một số tính năng nổi bật:
createSlicegiúp tạo reducer và action trong một dòng.configureStoretự động thiết lập thunk, devtools, và middleware.createAsyncThunkhỗ trợ tạo async logic.
Ví dụ: Tạo slice người dùng
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
interface UserState {
id: string | null;
name: string;
loading: boolean;
}
const initialState: UserState = {
id: null,
name: '',
loading: false,
};
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
setName(state, action: PayloadAction<string>) {
state.name = action.payload;
},
},
extraReducers: (builder) => {
builder
.addCase(fetchUser.pending, (state) => {
state.loading = true;
})
.addCase(fetchUser.fulfilled, (state, action) => {
state.id = action.payload.id;
state.name = action.payload.name;
state.loading = false;
})
.addCase(fetchUser.rejected, (state) => {
state.loading = false;
});
},
});
export const { setName } = userSlice.actions;
export default userSlice.reducer;
React Query – Tóm tắt
React Query (RQ) chuyên xử lý fetch dữ liệu, caching, optimistic updates, và refetch khi cần. Một số tính năng chính:
useQueryđể fetch dữ liệu đơn giản.useMutationcho các thao tác POST/PUT/DELETE.- Caching tự động, stale time, và refetch options.
Ví dụ: Fetch danh sách bài viết
import { useQuery } from 'react-query';
function usePosts() {
return useQuery('posts', async () => {
const res = await fetch('/api/posts');
return res.json();
});
}
export default usePosts;
Tích hợp Redux Toolkit và React Query
Mỗi thư viện phục vụ mục tiêu riêng: RTK cho state logic và phân phối toàn cục, RQ cho fetch, caching và sync dữ liệu từ server. Để kết hợp chúng, ta có thể:
- Sử dụng RTK để lưu trữ dữ liệu đã fetch: Khi RQ fetch dữ liệu thành công, dispatch một action lưu dữ liệu vào store.
- Dùng RTK query: RTK Query (phần mở rộng của RTK) có thể thay thế RQ trong một số trường hợp, nhưng nếu muốn đồng bộ giữa RTK Query và RQ, bạn có thể lắng nghe
onSuccesscủa query. - Lọc tác động: Đặt dữ liệu fetched từ RQ vào state của RTK để các component khác có thể subscribe mà không cần fetch lại.
Mã ví dụ: Ghi dữ liệu từ RQ vào RTK
import { useDispatch } from 'react-redux';
import { useQuery } from 'react-query';
import { setPosts } from './store/postSlice';
function Posts() {
const dispatch = useDispatch();
const { data, error, isLoading } = useQuery('posts', fetchPosts, {
onSuccess: (data) => {
dispatch(setPosts(data)); // lưu vào RTK
},
});
if (isLoading) return <p>Đang tải...</p>;
if (error) return <p>Lỗi: {error.message}</p>;
return (
<ul>
{data.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
Mẹo và thực hành
- Chỉ lưu dữ liệu quan trọng vào Redux. Nếu dữ liệu chỉ cần sử dụng trong component, giữ trong hook local.
- Sử dụng
select: Khi lấy dữ liệu từ RTK store, dùnguseSelectorvới selector tốt để tránh re-render không cần thiết. - Cấu trúc thư mục: Tách riêng
store/(Redux),queries/(React Query hooks), vàcomponents/. - Error handling: RQ cung cấp
onError, RTK để quản lý lỗi đồng bộ. - Testing: Khi sử dụng RTK + RQ, test hook RQ bằng mock
react-queryprovider, và test slice riêng.
Kết luận
Kết hợp Redux Toolkit với React Query giúp bạn tận dụng tối đa ưu điểm của hai công cụ: quản lý state đồng bộ, logic phức tạp và fetch dữ liệu hiệu quả, caching tốt, và đồng bộ dữ liệu một cách mượt mà. Đừng ngại thử nghiệm cách chia nhỏ dữ liệu giữa store và hook; một cấu hình hợp lý sẽ làm cho codebase dễ bảo trì và mở rộng.