Quản lý trạng thái với Provider và StateNotifier

Hello!
Nếu bạn đã từng sử dụng Provider thì chắc hẳn bạn cũng sẽ tận dụng luôn ChangeNotifierProvider hoặc ValueListenableProvider hoặc cái gì gì đó tương tự để quản lý “Nhà nước” luôn cho tiện đúng không.

ChangeNotifier thì mình đã dùng khá nhiều, đối với những screen có state đơn giản thì kiểm soát nó khá dễ và code cũng rất gọn, nhưng nếu với những screen có state phức tạp, cần quản lý rất nhiều trường thì nó dẫn tới tình trạng là toàn bộ getters vốn lẽ ra chỉ nên đặt tại Model/State thì giờ lại phải mang toàn bộ chúng paste vào ChangeNotifier thêm một lần nữa. Bên dưới là một đoạn code trong project cũ của mình.

Khá là dài dòng đúng không nhỉ :3
Đó là vấn đề của ChangeNotifier, mình nghĩ ra một cách giải quyết vấn đề đó là không expose toàn bộ các trường của state nữa mà thay vào đó thì chỉ expose duy nhất là state object thôi. Tới đây thì ValueNotifier sẽ là giải phát phù hợp hơn vì nó chỉ cần lắng nghe thay đổi của đúng một thằng là State thôi.

Giới thiệu package

Mình mới đi lang thang trên mạng và tìm thấy thằng StateNotifier được giới thiệu là tương đồng với ValueNotifier nhưng khắc phục được một số vấn đề của ValueNotifierChangeNotifier nên tò mò sử dụng thử. Một vài thông tin thêm về StateNotifier đó là tác giả của nó cũng chính là tác giả của package Provider nên mình cũng thêm phần tin tưởng :D Sự khác nhau giữa ValueNotifierStateNotifier bạn có thể xem tại đây differences-with-valuenotifier.

Tạo một StateNotifier

Bây giờ hãy thử tạo một class StateNotifier của riêng mình để quản lý trạng thái nha.
StateNotifier là một abstract class nên mình phải tạo 1 class extends StateNotifier<State> trong đó State chính là type của state object của mình. Như mình đã comment trong code thì chúng ta cần chú ý rằng: muốn StateNotifier nhận ra được có sự thay đổi của state thì buộc chúng ta phải tạo ra một instance mới của state mỗi lần muốn cập nhật một thứ gì đó.

Tạo một State

Vậy là mình đã tạo xong 1 lớp kết thừa StateNotifier rồi bây giờ sẽ tới bước tạo State chính là cái class MyState ở trên đó. Như đã đề cập ở trên thì muốn thông báo rằng state thay đổi thì cần tạo ra một instance khác của state. Và mình lại tìm được 1 package nữa hỗ trợ tạo ra một object cứng (không có sự thay đổi về giá trị bên trong) tên là Freezed cũng do tác giả của Provider tạo ra luôn :D. Thông tin chi tiết về package này bạn có thể xem thêm tại đây Freezed.
Sở dĩ mình đưa phần tạo State này về sau là bởi ở StateNotifier cần tạo mới instance state mỗi lần update nên mình giới thiệu sau cho dễ hiểu.
Nếu như bạn không muốn sử dụng Freezed thì có thể tạo một class thế này

Tạo một View

Phần trạng thái và quản lý trạng thái đã xong rồi, bây giờ tới phần cuối dùng là phần View. Ở hàm main hình có setup MultiProvider, bạn để ý phần này nhé Cái này cũng tương tự như ChangeNotifierProvider nhưng khác ở chỗ là nó cung cấp cùng lúc cả StateNotifierState. Ở phần View thì vẫn sử dụng Selector/Consumer/context.watch … như bình thường để có thể lấy ra được StateNotifier/State và sử dụng bình thường.

Kết luận

  1. Sử dụng StateNotifier sẽ làm cho phần quản lý trạng thái chỉ có chức năng là xử lý logic và cập nhật trạng thái tương ứng.
  2. State sẽ lưu trữ getters và các hàm liên quan chứ không đặt ở phần quản lý trạng thái nữa Có hiệu năng tốt hơn ValueNotifier (theo tác giả của package).
  3. Phân tách code giữa View/Logic/Model rõ ràng hơn ChangeNotifier Toàn bộ source code, các thư viện liên quan bạn có thể xem tại Đây.
Hãy để lại ý kiến của bạn dưới phần bình luận nhé :D

2 Nhận xét

Mới hơn Cũ hơn