หลักการออกแบบเบื้องหลัง miniriverpod.

แพ็กเกจนี้จงใจลดทอนฟีเจอร์เพื่อให้พฤติกรรมชัดเจน: เอกลักษณ์ของ provider ด้วย args, การ inject แบบ scoped และ semantics ของการ dispose ที่คาดเดาได้.

สิ่งที่เปลี่ยนไปจาก Riverpod

แทนที่จะใช้ generated family classes และ channels ของ notifier แบบ implicit, miniriverpod เลือก subclass + args + explicit invoke.

เอกลักษณ์ของ provider

runtimeType + hash ของ args

ทางเลือกแทน family

สืบทอด Provider / AsyncProvider และส่ง super.args((...))

DI fallback

Scope<T>.required + overrideWithValue

ทำไมสิ่งนี้จึงสำคัญ

คุณสามารถใช้ constructor ของ Dart ปกติเพื่อให้เหตุผลเกี่ยวกับ equality และ overrides ได้ ซึ่งทำให้การ debug และการทดสอบตรงไปตรงมา.

การระบุ Provider ด้วย args

args กำหนดคีย์ของ provider ดังนั้น args ที่เท่ากันหมายถึง cache entry เดียวกันภายใน ProviderContainer.

กฎเอกลักษณ์

ผลลัพธ์เชิงปฏิบัติ

- ไม่จำเป็นต้องมี family type แยกต่างหาก.
- การ override ราย argument ทำได้โดยการสร้าง provider instances.
- ควรรักษา args ให้คงที่และไม่เปลี่ยนแปลงเพื่อ caching ที่คาดเดาได้.

ตัวอย่าง: provider แบบ family + Scope สำรอง

ใช้ argument ของ constructor เป็นตัวระบุ และ inject instance สำรองผ่าน Scope.

class ProductProvider extends AsyncProvider<List<Product>> {
  ProductProvider({this.search = ''}) : super.args((search,));
  final String search;

  static final fallback = Scope<ProductProvider>.required('product.fallback');

  @override
  FutureOr<List<Product>> build(ref) async {
    final api = ref.watch(productsApiProvider);
    return api.search(q: search);
  }
}

// แทรก
ProviderScope(
  overrides: [
    ProductProvider.fallback.overrideWithValue(ProductProvider(search: 'jeans')),
  ],
  child: const App(),
);
Scope ทำให้การเชื่อมโยง dependency ชัดเจนและเป็นมิตรต่อการทดสอบ.
overrideWithValue ทำงานต่อ provider instance แต่ละตัว รวมถึง instances ที่อิง args.
พฤติกรรม autoDispose ไม่เปลี่ยนเมื่อใช้ subclass + args.

ขั้นตอนถัดไป

Providers และการอ่าน

ดูรูปแบบที่เป็นรูปธรรมสำหรับ watch/read/listen และ AsyncProvider.future.

เปิด Providers

มิวเทชัน

ใช้งานการอัปเดตสถานะด้วย mutation tokens, mutate และ ref.invoke.

เปิดมิวเทชัน