1. Vậy State Management là gì?
Hiểu một cách đơn giản State dùng để thể hiện các trạng thái của các thành phần trong một ứng dụng web hoặc app, được thể hiện ra qua giao diện để người dùng nhìn thấy. Tuy nhiên, cũng có những State được sinh ra để xử lý chạy ngầm trong ứng dụng mà không thể hiện ra giao diện người dùng. Vì thế trong một ứng dụng web hoặc app sẽ có thể có rất nhiều State, đôi khi chúng hoạt động 1 cách độc lập hoặc phụ thuộc, ràng buộc lẫn nhau nên chúng ta cần phải quản lý nó. Đó chính là State Management.
2. Redux là gì? Vì sao người ta thường dùng Redux Toolkit trong việc quản lý State Management
Redux là một thư viện quản lý trạng thái (predictable state management tool) cho các ứng dụng Javascript. Nó giúp chúng ta dễ dàng xây dựng được các ứng dụng hoạt động một cách nhất quán, linh hoạt trên nhiều môi trường khác nhau (client, server, and native) và dễ dàng kiểm thử.
Redux là sự kết hợp sáng tạo từ ngôn ngữ Elm và kiến trúc Flux của Facebook, Vì thế nên 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 một ứng dụng, giúp tách biệt logic và giao diện người dùng. Dễ tiếp cận và theo dõi, Redux giúp chúng ta theo dõi và cập nhật trạng thái các component 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.
Trong một ứng dụng, data được chia sẻ thông qua các components, vì thế rất dễ nhầm lẫn để chúng ta có thể thực sự biết state này đang thuộc component nào. Vì vậy việc share data thông qua các components anh em sẽ trở nên khó khăn hơn.
Giờ hãy nhìn vào mô hình bên dưới và làm 1 phép so sánh giữa việc không dùng redux để quản lý state(without redux) và dùng redux để quản lý state(with redux)
Khi không sử dụng redux hãy hình dung rằng nếu một state phải được chia sẻ giữa các component khác nhau và cách khá xa nhau trong một tree components và state này phải được passed từ một component đến một component khác cho đến khi nó đến được nơi mà nó được gọi để sử dụng.
Một component chỉ có thể truyền state của nó tới các component con như là các props. Các component con không quan tâm props nhận được là props hay state của cha. Các component con chỉ việc sử dụng chúng. Bất kì state nào cũng được sở hữu bởi một component cụ thể. Và bất kì dữ liệu nào liên quan đến state đó chỉ có thể ảnh hưởng đến các component “bên dưới” chúng. Hiểu đơn giản như là dòng chảy thác nước.
Khi sử dụng Redux thì Redux hoạt động một cách khá là đơn giản. Nó có một store lưu trữ toàn bộ state của ứng dụng. Mỗi component có thể truy cập trực tiếp đến state được lưu trữ trong store thay vì phải gửi dữ liệu lần lượt từ component này đến component khác.
3. Cách hoạt động của Redux
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à trong một Redux sẽ có 3 thành phần chính mà chúng ta cần quan tâm đó là: Store, Reducer và Action.
Actions
Actions (hiểu đơn giản là các events): là cách để gửi dữ liệu(request data) từ ứng dụng đến thư viện(Redux Store). Khi mà trạng thái của app hoặc khi render của view thay đổi thì sẽ có một hành động sẽ được tạo ra.
Những dữ liệu này có thể là từ sự tương tác của user vs app, API calls hoặc cũng có thể là từ form submission.
Action là một hàm đơn giản trả về một đối tượng và có trách nhiệm gửi dữ liệu đến kho lưu trữ (store) thông qua hàm dispatch và reducer. Nó có hai thuộc tính – payload và type. Hành động được gọi là “type” và giá trị được áp dụng để thay đổi trạng thái của ứng dụng được gọi là “payload”.
// Định nghĩa các action
Reducer
“Reducer” là một hàm được sử dụng để thay đổi trạng thái của ứng dụng theo cách phụ thuộc vào các loại action cụ thể. Hàm nhận hai đối số: trạng thái hiện tại và action, và trả về một trạng thái mới. Chức năng chính của reducer là tạo ra một trạng thái mới cho store.
Mỗi reducer có một trạng thái ban đầu và nhận vào trạng thái hiện tại và hành động để tính toán trạng thái mới.
Reducers là các hàm không thay đổi trạng thái gốc, mà thay vào đó trả về một trạng thái mới dựa trên trạng thái hiện tại và hành động.
// Định nghĩa reducer để xử lý các action liên quan thêm ‘Todo’
Store
Store: Là nơi quản lý State, cho phép truy cập State qua getState(), update State qua dispatch(action), đăng kí listener qua subscribe(listener).
Phương thức duy nhất để truy cập vào store là thông qua việc gửi action.
// Tạo một store cho một ToDoList app:
import { createStore } from 'redux' import messageReducer from './reducers' let store = createStore(messageReducer)
Redux còn có thêm 1 thành phần phụ nữa là Middleware.
4. Cơ chế và nguyên lý vận hành của redux
Redux hoạt động dựa trên một số nguyên lý chính sau đây:
Single source of truth (Nguồn dữ liệu duy nhất) State của toàn bộ ứng được lưu trong một object tree nằm trong Store duy nhất. Store là một cây trạng thái không thể thay đổi trực tiếp.
State is read-only (Trạng thái chỉ đọc): có nghĩa là chúng ta không thể thay đổi trạng thái trực tiếp. Điều này đảm bảo tính nhất quán và theo dõi của trạng thái. Để thay đổi trạng thái chúng ta sẽ tạo ra một hành động (action) cập nhật sự thay đổi và dispath action đó đến reducers để tính toán trạng thái mới từ trạng thái hiện tại và hành động đó.
Changes are made with pure functions (Thay đổi được thực hiện bằng các hàm thuần túy): Reducer là các hàm thuần túy nhận vào trạng thái hiện tại và hành động, và trả về một trạng thái mới. Việc thay đổi trạng thái xảy ra thông qua việc gọi các reducer.
Unidirectional data flow (Luồng dữ liệu một chiều): Khi một hành động được gửi đến store, nó sẽ được chuyển đến reducer để xử lý và tạo ra trạng thái mới. Sau đó, trạng thái mới được cập nhật trong store và thông báo cho các thành phần ứng dụng khác về sự thay đổi.
Time-travel debugging (Gỡ lỗi theo thời gian): Redux hỗ trợ tính năng gỡ lỗi theo thời gian, cho phép bạn xem lại các hành động đã xảy ra và trạng thái tại mỗi thời điểm trong quá trình phát triển.
5. Làm thế nào để sử dụng Redux trong dự án của bạn?
Bước 1: Cài đặt Redux (npm i redux) trong ứng dụng mà bạn muốn sử dụng
Bước 2: Định nghĩa các actions mà các compoent sử dụng
Bước 3: Tạo reducer xử lý logic và cập nhật trạng thái của ứng dụng dựa trên action. Bạn cần tạo các reducer tương ứng với từng phần của ứng dụng.
Bước 4: Tạo store
Store là nơi chứa toàn bộ trạng thái của ứng dụng. Bằng cách sử dụng hàm createStore từ Redux, bạn có thể tạo store và truyền reducer vào.
Bước 5: Kết nối với giao diện người dùng
Hiện nay có rất nhiều thư viện giao diện người dùng như React, Angular. Bạn có thể sử Sử react-redux cho React hoặc @ngrx/store cho Angular để thực hiện việc này.
6. Kết luận
Qua bài viết này, chúng ta đã cùng tìm hiểu về Redux và những nguyên tắc cơ bản của nó. Redux không chỉ giúp quản lý trạng thái một cách hiệu quả mà còn đơn giản hóa việc theo dõi và duyệt qua lịch sử trạng thái của ứng dụng. Bằng cách sử dụng Redux, bạn có thể tạo ra các ứng dụng web mạnh mẽ và linh hoạt hơn bao giờ hết.