1. Provider & Notifier là gì?

Trong quá trình phát triển ứng dụng Flutter, State Management (quản lý trạng thái) là một phần quan trọng giúp quản lý dữ liệu và cập nhật giao diện khi dữ liệu thay đổi. Đối với những ứng dụng đơn giản, có thể sử dụng setState() để cập nhật trạng thái trong một Widget. Tuy nhiên, khi ứng dụng có nhiều màn hình và nhiều thành phần cần sử dụng chung dữ liệu, việc quản lý State cần được tổ chức rõ ràng hơn.

Provider và Notifier là hai khái niệm thường gặp khi sử dụng thư viện Riverpod để quản lý State. Chúng có vai trò khác nhau nhưng có thể kết hợp với nhau để giúp ứng dụng quản lý dữ liệu hiệu quả hơn.

Provider là thành phần dùng để cung cấp dữ liệu, đối tượng hoặc trạng thái cho những phần khác trong ứng dụng truy cập và theo dõi. Nhờ Provider, các Widget không cần tự tạo và quản lý riêng từng dữ liệu mà có thể sử dụng dữ liệu được cung cấp từ một nơi.

Notifier là thành phần chịu trách nhiệm quản lý State và định nghĩa các phương thức để thay đổi State đó. Khi dữ liệu thay đổi, Notifier có thể cập nhật trạng thái mới để những Widget đang theo dõi nhận được thông tin và cập nhật giao diện tương ứng.

Có thể hiểu đơn giản rằng Provider giúp cung cấp và theo dõi dữ liệu, còn Notifier chịu trách nhiệm quản lý và thay đổi dữ liệu trong những trường hợp cần cập nhật State.

  1. Provider & Notifier hoạt động như thế nào?

Để hiểu rõ hơn, hãy lấy ví dụ về chức năng giỏ hàng trong một ứng dụng bán sữa.

Khi khách hàng thêm sản phẩm vào giỏ hàng, số lượng sản phẩm sẽ thay đổi. Thông tin này có thể cần được sử dụng ở nhiều nơi, chẳng hạn biểu tượng giỏ hàng trên thanh điều hướng, màn hình giỏ hàng và trang thanh toán.

Nếu mỗi màn hình tự quản lý một số lượng riêng, dữ liệu có thể không đồng nhất. Ví dụ, giỏ hàng có ba sản phẩm nhưng biểu tượng trên thanh điều hướng vẫn hiển thị hai sản phẩm.

Để giải quyết vấn đề này, có thể sử dụng Notifier để quản lý dữ liệu giỏ hàng và cung cấp các phương thức như thêm sản phẩm, xóa sản phẩm hoặc cập nhật số lượng. Provider giúp các Widget cần thiết truy cập và theo dõi trạng thái giỏ hàng đó.

Quy trình hoạt động có thể diễn ra như sau:

Người dùng thêm sản phẩm → Notifier xử lý thao tác và cập nhật State → Provider cung cấp trạng thái mới cho các Widget đang theo dõi → Giao diện cập nhật số lượng sản phẩm

Trong Riverpod, NotifierProvider thường được sử dụng để kết hợp một Notifier với State mà nó quản lý. Khi State thay đổi, các Widget theo dõi Provider có thể được thông báo và cập nhật theo dữ liệu mới.

  1. Một số loại Provider và Notifier thường gặp

Trong Riverpod, có nhiều loại Provider phù hợp với những nhu cầu khác nhau:

  • Provider: Dùng để cung cấp một giá trị hoặc đối tượng, chẳng hạn một dịch vụ xử lý dữ liệu hoặc một Repository.
  • StateProvider: Trong các phiên bản Riverpod trước đây, thường được sử dụng cho State đơn giản. Khi sử dụng Riverpod hiện đại, cần chú ý phiên bản và hướng dẫn hiện hành vì API này đã được đánh dấu không khuyến nghị trong các phiên bản mới.
  • NotifierProvider: Dùng để cung cấp State được quản lý bởi một Notifier, phù hợp khi cần xây dựng các phương thức thay đổi dữ liệu và xử lý logic.
  • AsyncNotifierProvider: Phù hợp với State cần xử lý bất đồng bộ, chẳng hạn tải danh sách sản phẩm từ API hoặc lấy thông tin người dùng từ máy chủ.

Việc lựa chọn loại Provider phụ thuộc vào tính chất dữ liệu và cách ứng dụng cần quản lý trạng thái.

  1. Ví dụ minh họa trong Flutter

Giả sử ứng dụng bán sữa cần quản lý số lượng sản phẩm trong giỏ hàng. Có thể tạo một Notifier để lưu số lượng hiện tại và cung cấp phương thức tăng số lượng:

import 'package:flutter_riverpod/flutter_riverpod.dart';

class CartNotifier extends Notifier<int> {
  @override
  int build() => 0;

  void addProduct() {
    state++;
  }
}

final cartProvider = NotifierProvider<CartNotifier, int>(
  CartNotifier.new,
);

Trong ví dụ trên, CartNotifier chịu trách nhiệm quản lý State có kiểu dữ liệu int. Phương thức build() khởi tạo số lượng ban đầu bằng 0. Khi gọi addProduct(), giá trị state tăng lên một đơn vị.

cartProvider giúp các Widget truy cập và theo dõi State này. Trong một Widget sử dụng WidgetRef, có thể gọi ref.watch(cartProvider) để theo dõi số lượng sản phẩm và gọi ref.read(cartProvider.notifier).addProduct() để yêu cầu tăng số lượng.

Đây là ví dụ đơn giản để minh họa cách hoạt động. Trong ứng dụng thực tế, giỏ hàng thường cần quản lý danh sách sản phẩm, số lượng từng sản phẩm, giá tiền và các thao tác liên quan.

  1. Ưu điểm và những điểm cần lưu ý

Provider và Notifier giúp tập trung việc quản lý dữ liệu, hạn chế việc truyền dữ liệu qua nhiều Widget và giúp giao diện sử dụng chung một nguồn State. Khi được tổ chức hợp lý, mã nguồn sẽ dễ đọc, dễ kiểm thử và thuận tiện hơn khi mở rộng tính năng.

Tuy nhiên, cần phân biệt rõ trách nhiệm của từng thành phần. Provider không nhất thiết phải trực tiếp xử lý toàn bộ nghiệp vụ, còn Notifier nên tập trung vào việc quản lý State và những thao tác liên quan đến State đó. Đối với các nghiệp vụ phức tạp, có thể tách phần truy cập dữ liệu hoặc gọi API sang Repository hay Service riêng.

Ngoài ra, không nên tạo quá nhiều Provider nếu không cần thiết. Việc chia nhỏ nên dựa trên trách nhiệm của dữ liệu và nhu cầu sử dụng để tránh khiến cấu trúc dự án trở nên khó hiểu.

  1. Kết luận

Provider và Notifier là những thành phần hữu ích trong việc quản lý State bằng Riverpod trong Flutter. Provider giúp cung cấp dữ liệu cho những thành phần cần sử dụng, còn Notifier quản lý State và định nghĩa các phương thức thay đổi dữ liệu. Khi kết hợp hợp lý, chúng giúp ứng dụng cập nhật giao diện chính xác, giảm sự phụ thuộc giữa các Widget và tổ chức mã nguồn dễ bảo trì hơn.

 

Bài viết khác

BÀI 5: TÌM HIỂU CHUYÊN SÂU VỀ LANGUAGE SWITCHING TRONG FLUTTER

1. Language Switching là gì? Trong một ứng dụng hỗ trợ nhiều ngôn ngữ, việc có sẵn các bản dịch chưa đủ để tạo ra trải nghiệm đa ngôn ngữ hoàn chỉnh. Ứng dụng còn cần xác định ngôn ngữ nào sẽ được sử dụng và cho phép thay đổi ngôn ngữ khi cần thiết. […]

TÌM HIỂU CHUYÊN SÂU VỀ UTC & LOCAL TIME CONVERSION TRONG FLUTTER

1. UTC & Local Time Conversion là gì? Trong một ứng dụng Flutter, thời gian xuất hiện ở rất nhiều chức năng như ngày tạo tài khoản, thời gian đặt hàng, lịch sử giao dịch, lịch hẹn, thời gian gửi thông báo và thời hạn của chương trình khuyến mãi. Khi ứng dụng chỉ chạy […]

TÌM HIỂU CHUYÊN SÂU VỀ DATE / NUMBER / CURRENCY FORMATTING TRONG FLUTTER

1. Date / Number / Currency Formatting là gì? Trong một ứng dụng Flutter, dữ liệu thường được lưu trữ và xử lý dưới dạng số, ngày giờ hoặc các kiểu dữ liệu có cấu trúc. Tuy nhiên, dữ liệu dùng để tính toán không nhất thiết giống với cách dữ liệu được hiển thị […]

TÌM HIỂU CHUYÊN SÂU VỀ LOCALIZATION (l10n) TRONG FLUTTER

1. Localization (l10n) là gì? Khi một ứng dụng được sử dụng ở nhiều quốc gia, sự khác biệt không chỉ nằm ở ngôn ngữ mà còn ở cách người dùng đọc ngày tháng, số, tiền tệ, đơn vị đo lường và các thông tin trên giao diện. Ví dụ, một ứng dụng bán hàng […]

TÌM HIỂU CHUYÊN SÂU VỀ INTERNATIONALIZATION (i18n) TRONG FLUTTER

1. Internationalization (i18n) là gì? Trong quá trình phát triển ứng dụng, lập trình viên thường xây dựng giao diện bằng một ngôn ngữ ban đầu, chẳng hạn như tiếng Việt. Khi ứng dụng được sử dụng bởi người dùng ở nhiều quốc gia, việc chỉ hỗ trợ một ngôn ngữ có thể khiến người […]

TÌM HIỂU CHUYÊN SÂU VỀ APP RELEASE & DEPLOYMENT TRONG FLUTTER

1. App Release & Deployment là gì? Trong quá trình phát triển ứng dụng Flutter, sau khi hoàn thành các chức năng, lập trình viên cần đưa ứng dụng đến người dùng thực tế. Ví dụ, một nhóm đã xây dựng xong ứng dụng bán hàng với những chức năng như đăng nhập, xem sản […]

Leave a Reply

Your email address will not be published. Required fields are marked *