Redux là gì? Vì sao người ta thường dùng Redux cùng ReactJS? Cùng 200Lab cập nhật kiến thức Redux cơ bản & ứng dụng hữu ích nhé!
1. Redux là gì?
Redux là một thư viện quản lý trạng thái (state management) tương thích với các ứng dụng web, phổ biến trong việc phát triển ứng dụng front-end sử dụng JavaScript và ReactJS.
Đây là một công cụ hữu ích giúp bạn xây dựng các ứng dụng có tính nhất quán, hoạt động linh hoạt trên nhiều môi trường (client, server và native), và dễ dàng kiểm thử. Sáng tạo từ ngôn ngữ Elm và kiến trúc Flux của Facebook, Redux thường được kết hợp sử dụng cùng với React.
Redux có nhiệm vụ quản lý trạng thái phức tạp trong ứng dụng web, giúp tách biệt logic và giao diện người dùng. Với tiếp cận dễ hiểu và theo dõi, Redux giúp bạn theo dõi và cập nhật trạng thái một cách hiệu quả, đồng thời đảm bảo tính nhất quán cho dữ liệu trong ứng dụng, từ đó dễ dàng debug khi gặp lỗi.
Nếu bạn muốn tìm hiểu thêm về Redux, bạn có thể xem qua các bài viết từ trang Blog Lập Trình & Dữ Liệu của 200Lab nhé.
2. Tại sao lập trình viên nên dùng Redux?
Khi ứng dụng web Frontend của chúng ta ngày càng lớn, có thêm nhiều component hơn, đồng nghĩa với việc sẽ sinh ra nhiều state. Có những state chúng ta sử dụng trong phạm vi component hiện tại, nhưng sẽ có những state ta sẽ sử dụng ở nhiều component khác nhau, và các component mà ta sử dụng nằm rải rác trong source code của chúng ta.
Việc truyền state thông qua props theo cách truyền thống từ cha xuống con sẽ không còn hiệu quả nếu như 2 component cần sử dụng chung 1 state nằm quá xa nhau. Trong thực tế chúng ta sẽ gặp trường hợp sau:
Nếu như chưa biết đến Redux thì giải pháp cho trường hợp trên của các bạn là gì? Làm sao để cả Admin.jsx
với News.jsx
đều truy cập được state userDetail?
Hướng dẫn truy cập state userDetail trên Redux
1. Call API ở những nơi cần sử dụng
Cách đầu tiên là làm tương tự như ở file Header.jsx
, đấy là component nào cần sử dụng userDetail thì ta call api ở component đấy. Đây là cách nhanh và đơn giản nhất nhưng nó lại có vài vấn đề. Đó là nó làm api bị call nhiều lần.
Bạn thử tưởng tượng Header nằm trong trang Admin, khi 2 component này được render, nó sẽ call đến api kia một lần, và mỗi khi 1 trong 2 component này re-render, nó sẽ lại call tiếp.
Việc này ảnh hưởng rất lớn đến performance của website, khiến website của chúng ta chậm đi đáng kể. Nên đây không phải là cách chúng ta nên làm đúng không?
2. Lưu dữ liệu call từ api xuống localStorage
Cách thứ hai có thể nghĩ đến là lưu dữ liệu call từ api xuống localStorage, component nào cần dùng thì gọi ra để sử dụng là xong.
Cách này sẽ giải quyết được vấn đề của cách đầu tiên, là api sẽ không bị gọi đi gọi lại nhiều lần không cần thiết, nhưng nó lại sinh ra 2 vấn đề:
- Một là làm website của chúng ta chậm lại vì việc format dữ liệu từ localStorage, ta phải sử dụng đến hàm stringify và parse để xử lý dữ liệu khi lưu xuống và lấy ra từ localStorage.
- Hai là dữ liệu từ localStorage sẽ không tự đồng bộ ở tất cả component khi giá trị của state đó bị thay đổi.
Từ những vấn đề trên mà state management như Redux ra đời, Redux đã khắc phục được toàn bộ nhược điểm bên trên, giúp quản lý state hiệu quả hơn rất nhiều.
3. Redux hoạt động như thế nào?
Vậy để quản lý các state hiệu quả thì Redux đã làm gì?
Redux sẽ đưa tất cả các state vào một kho lưu trữ chung gọi là Store, khi component nào đó muốn sử dụng state có trong Store thì sẽ gọi vào Store thông qua Reducer. Và để thực hiện hành động đối với các state này thì chúng ta sẽ tạo ra các Action.
Vậy là sẽ có 3 thành phần chính của Redux mà chúng ta cần quan tâm đó là: Store, Reducer và Action.
3.1. Store trên Redux là gì?
Store là nơi Redux dùng để lưu toàn bộ state của ứng dụng. Nó giống như một cái nhà kho vậy, khi một component có nhu cầu sử dụng state nào đấy chỉ cần vào trong store để lấy ra.
3.2. Reducer trên Redux là gì?
Là các hàm xử lý các hành động cụ thể và thay đổi state của ứng dụng. Reducer nhận vào giá trị của state hiện tại và hành động bạn muốn thực hiện, rồi trả ra state mới dựa trên hành động đó.
3.3. Action trên Redux là gì?
Là hành động mà bạn muốn thực hiện với state đó. Ví dụ đơn giản nhất là việc thay đổi giá trị của state.
Redux còn có thêm 1 thành phần phụ nữa là Middleware.
3.4. Tìm hiểu về Middleware trên Redux
Là các lớp trung gian giúp xử lý các hành động trước khi chúng đến Reducer. Middleware thường được sử dụng để thực hiện các tác vụ như gọi API, xử lý bất đồng bộ,...
Dưới đây là hình ảnh miêu tả cách hoạt động của Redux:
Luồng xử lý của Redux như sau:
- Trường hợp không sử dụng Middleware: State được khởi tạo bên trong Store -> State được đưa vào Reducer -> Reducer khởi tạo giá trị state ban đầu (initialState) -> Thực hiện action ở component (dispatch event) -> Thay đổi giá trị của state bên trong Reducer thành state mới -> Đẩy state mới ra ngoài View (component)
- Trường hợp sử dụng Middleware: State được khởi tạo bên trong Store -> State được đưa vào Reducer -> Reducer khởi tạo giá trị state ban đầu (initialState) -> Thực hiện action ở component (dispatch event) -> Gọi API ở Middleware -> Đưa dữ liệu vừa gọi vào Reducer -> Thay đổi giá trị của state bên trong Reducer thành state mới -> Đẩy state mới ra ngoài View (component).
Các bạn có thể xem cách setup một ứng dụng To do list sử dụng Redux ở ví dụ dưới đây:
Vậy luồng xử lý của Redux trong ứng dụng TodoList này hoạt động như thế nào?
- Khai báo constants: Để code của chúng ta trong gọn và dễ maintain hơn, việc đầu tiên chúng ta cần làm là khai báo các constant cần sử dụng với Redux. Các constants được khai báo ở file
src/redux/actionTypes.js
- Khởi tạo state: giá trị state ban đầu của redux sẽ được khai báo ở
src/redux/reducer.js
- Khởi tạo các reducer: Khởi tạo reducer với tên các hành động lấy từ
src/redux/actionTypes.js
. - Khởi tạo các actions: Các action được khởi tạo ở
src/redux/actions.js
Giải thích các Reducer:
ADD_TODO
: Khi user gửi action tên làADD_TODO
, reducer sẽ trả về một state mới với danh sách todo được cập nhật bằng cách thêm payload (todo mới) vào cuối danh sách hiện có.TOGGLE_STATUS
:Khi user gửi action tên làTOGGLE_STATUS
, reducer chỉ cập nhật lại mảng todo bằng payload (mảng mới) để thay đổi trạng thái của todo (đã hoàn thành hay chưa).DELETE_TODO
: Khi user gửi action tên làDELETE_TODO
, reducer cũng chỉ cập nhật lại mảng todo bằng payload mới để xoá công việc khỏi danh sách.
Các hàm handleClick(), handleToggle(), handleDelete() đều xử lý dữ liệu todo rồi trả về mảng todo mới, sau đó cập nhật vào Redux thông qua việc dispatch một action.
4. Redux Toolkit là gì?
Redux Toolkit là thư viện được phát triển bởi ReduxJS, giúp viết mã Redux nhanh chóng, toàn diện và tuân thủ chuẩn mực. Nó giải quyết vấn đề phức tạp của Redux và cung cấp API tiện ích để viết mã ngắn gọn, dễ đọc hơn và tuân theo các mẫu thiết kế tốt nhất.
Một số lập trình viên cảm thấy Redux hơi dài dòng và khó sử dụng. Tạo một store hoàn chỉnh đòi hỏi nhiều bước và tạo nhiều tệp lặp đi lặp lại. Redux Toolkit được ra đời, nhằm tối giản hoá cách setup và sử dụng, giúp lập trình viên có thể tập trung hơn vào việc xử lý logic thay vì mất quá nhiều thời gian ban đầu để set-up.
Hiện tại Redux Toolkit đang được sử dụng rất phổ biến, các bạn có thể xem ví dụ về một ứng dụng Todo list sử dụng Redux Toolkit dưới đây:
Trông đơn giản hơn rất nhiều đúng không nè?
5. Lưu ý khi sử dụng Redux
- Giá trị lưu trong Redux về bản chất vẫn là state nên nó thừa hưởng mọi tính chất của state, chỉ khác ở chỗ nó là global state (state toàn cục) nên khi giá trị lưu trong Redux thay đổi thì tất cả component đang sử dụng giá trị đó cũng sẽ thay đổi theo.
- Chuẩn hoá dữ liệu (Normalized State) trước khi lưu chúng vào Redux để đảm bảo hiệu suất của ứng dụng đạt ở mức cao.
- Nên thực hiện việc xử lý logic ở các hàm bên ngoài, hạn chế xử lý logic phức tạp bên trong Redux, Redux chỉ nên sử dụng để lưu dữ liệu cuối cùng sau khi đã qua xử lý.
6. Nên sử dụng Redux trong trường hợp nào?
Redux không phải lúc nào cũng cần thiết, việc xác định được ứng dụng web của bạn có cần sử dụng Redux hay không là rất quan trọng. Vì việc sử dụng Redux không đúng cách có thể làm ứng dụng của bạn chậm đi đáng kể, ảnh hưởng đến performance. Với những ứng dụng web nhỏ bạn có thể sử dụng state nội bộ hoặc các state management gọn nhẹ hơn như ContextAPI, Recoil,...
Vậy thì những trường hợp nào chúng ta nên sử dụng Redux?
- Quản lý nhiều state phức tạp: Khi ứng dụng web của bạn cần quản lý nhiều state phức tạp và chúng cần tương tác với nhau, việc sử dụng Redux sẽ giúp bạn quản lý các state dễ dàng hơn
- State cần chia sẻ global: Khi nhiều component cần sử dụng chung 1 state, việc sử dụng Redux sẽ giúp các component truy cập dễ dàng hơn so với việc sử dụng props
- Lưu lại lịch sử của state và actions: Redux cho phép bạn theo dõi lịch sử của các state và actions, điều này rất hữu ích cho việc debug về sau. Redux còn có extension trên Chrome tên là Redux DevTools, giúp chúng ta có thể dễ dàng theo dõi lịch sử thay đổi của state và actions ngay trên trình duyệt.
7. Kết luận về Redux
Việc sử dụng Redux ngày nay đã trở nên rất phổ biến ở các ứng dụng web hiện đại, nó giúp hiệu suất ứng dụng web của chúng ta được cải thiện hơn rất nhiều cũng như giúp các lập trình viên có thể làm việc với nhau hiệu quả hơn, tốn ít công sức hơn.
(*) Bài viết này có tham khảo tài liệu tại đây.
Giờ thì bạn đã hiểu được khái niệm "Redux là gì?" cũng như cách hoạt động của Redux. Hãy theo dõi 200Lab để đọc thêm các bài viết hay nhé. Chúc bạn khám phá Redux thật vui vẻ.
Những bài viết bạn sẽ thích:
Bài viết liên quan
React Toastify là gì? Hướng dẫn sử dụng Toast Notification với React Toastify
Nov 21, 2024 • 7 min read
Hướng dẫn sử dụng Zustand trong NextJS
Nov 21, 2024 • 8 min read
Lazy Loading: Kỹ thuật Tối ưu Hiệu suất Website
Nov 17, 2024 • 14 min read
Hướng dẫn sử dụng Redux Toolkit và Redux Saga trong dự án React
Nov 15, 2024 • 10 min read
WebGL là gì? Hướng dẫn tạo đồ họa đơn giản với WebGL
Nov 13, 2024 • 7 min read
Test-Driven Development (TDD) là gì? Hướng dẫn thực hành TDD
Nov 13, 2024 • 6 min read