Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Flutter Consumer Widget
Gülsen Keskin
Gülsen Keskin

Posted on • Edited on

     

Flutter Consumer Widget

Consumer widget'ın iki ana amacı vardır:
BuildContext'imiz olmadığında ve bu nedenle Provider.of'u kullanamadığımızda provider'dan bir değer alınmasına izin verir.

Bu senaryo genellikle, aşağıdaki örnekte olduğu gibi, provider'ı oluşturan widget öğesi aynı zamanda consumer'lardan biri olduğunda gerçekleşir:

@overrideWidget build(BuildContext context) {  return ChangeNotifierProvider(    create: (_) => Foo(),    child: Text(Provider.of<Foo>(context).value),  );}
Enter fullscreen modeExit fullscreen mode

Provider.of, provider'ının atası olan bir BuildContext ile çağrıldığından, bu örnek bir ProviderNotFoundException oluşturacaktır.

Bunun yerine, Provider.of'u kendi BuildContext'i ile çağıracak olan Consumer widget öğesini kullanabiliriz.

Consumer kullanarak önceki örneği şöyle yazabiliriz:

@overrideWidget build(BuildContext context) {  return ChangeNotifierProvider(    create: (_) => Foo(),    child: Consumer<Foo>(      builder: (_, foo, __) => Text(foo.value),    },  );}
Enter fullscreen modeExit fullscreen mode

Bu, ProviderNotFoundException oluşturmaz ve Text'i doğru şekilde oluşturur. Ayrıca, foo değeri değiştiğinde Text'i de günceller.

Bu durum daha ayrıntılı yeniden oluşturmalar sağlayarak performans optimizasyonuna yardımcı olur.

Listen: false Provider.of'a geçirilmediği sürece, Provider.of'a geçirilen BuildContext ile ilişkili widget öğesi, elde edilen değer değiştiğinde yeniden oluşturulur. Bu beklenen davranıştır, ancak bazen gerekenden daha fazla widget'ı yeniden oluşturabilir.

Örneğin:

 @override Widget build(BuildContext context) {   return FooWidget(     child: BarWidget(       bar: Provider.of<Bar>(context),     ),   ); }
Enter fullscreen modeExit fullscreen mode

Yukarıdaki kodda, yalnızca BarWidget Provider.of tarafından döndürülen değere bağlıdır. Ancak Bar değiştiğinde, hem BarWidget hem de FooWidget yeniden oluşturulacaktır.

İdeal olarak, yalnızca BarWidget yeniden oluşturulmalıdır. Bunu başarmak için çözümConsumer kullanmaktır.

Bunu yapmak için, yalnızca provider'a bağlı olan widget öğelerini bir Consumer'a sararız:

 @override Widget build(BuildContext context) {   return FooWidget(     child: Consumer<Bar>(       builder: (_, bar, __) => BarWidget(bar: bar),     ),   ); }
Enter fullscreen modeExit fullscreen mode

Bu durumda, Bar güncellenirse yalnızca BarWidget yeniden oluşturulur.

Ama ya bir provider'a bağlı olan FooWidget ise? Örneğin:

 @override Widget build(BuildContext context) {   return FooWidget(     foo: Provider.of<Foo>(context),     child: BarWidget(),   ); }
Enter fullscreen modeExit fullscreen mode

Consumer ve isteğe bağlıchild argümanını kullanarak bu tür bir senaryoyu ele alabiliriz:

 @override Widget build(BuildContext context) {   return Consumer<Foo>(     builder: (_, foo, child) => FooWidget(foo: foo, child: child),     child: BarWidget(),   ); }
Enter fullscreen modeExit fullscreen mode

Bu örnekte, BarWidget builder'ın dışında oluşturulmuştur. Ardından, BarWidget örneği builder'a son parametre olarak iletilir.

Bu, Builder yeni değerlerle yeniden çağrıldığında, yeni bir BarWidget örneğinin oluşturulmayacağı anlamına gelir. Bu da, Flutter'ın BarWidget'ı yeniden oluşturması gerekmediğini bilmesini sağlar. Bu nedenle, böyle bir yapılandırmada, Foo değişirse yalnızca FooWidget yeniden oluşturulur.

Not:
Consumer widget'ı, MultiProvider içinde de kullanılabilir. Bunu yapmak için, oluşturucuya iletilen child'ı, oluşturduğu widget ağacında döndürmesi gerekir.

MultiProvider(  providers: [    Provider(create: (_) => Foo()),    Consumer<Foo>(      builder: (context, foo, child) =>        Provider.value(value: foo.bar, child: child),    )  ],);
Enter fullscreen modeExit fullscreen mode

Consumer widget'ının tek gerekli argümanı builder'dır.
Builder, ChangeNotifier değiştiğinde çağrılan bir fonksiyondur.
Başka bir deyişle, modelinizde notifyListeners() öğesini çağırdığınızda, karşılık gelen tüm Consumer widget öğelerinin tüm builder methodları çağrılır.

Builder üç argümanla çağrılır. İlki, her derleme yönteminde de aldığınız context'dir.

Builder fonksiyonunun ikinci argümanı, ChangeNotifier örneğidir(instance).

Üçüncü argüman, optimizasyon için orada olan child'dır. Consumer'ınızın altında model değiştiğinde değişmeyen büyük bir widget alt ağacınız varsa, onu bir kez oluşturabilir ve builder'dan (oluşturucudan) geçirebilirsiniz.

return Consumer<CartModel>(  builder: (context, cart, child) => Stack(    children: [    // SomeExpensiveWidget'ı her seferinde yeniden oluşturmadan burada kullanın.      if (child != null) child,      Text("Total price: ${cart.totalPrice}"),    ],  ),// Pahalı widget'ı burada oluşturun.  child: const SomeExpensiveWidget(),);
Enter fullscreen modeExit fullscreen mode

Consumer widget'larınızı ağacın mümkün olduğunca derinlerine yerleştirmek en iyi uygulamadır. Bazı ayrıntılar değişti diye kullanıcı arayüzünün büyük bölümlerini yeniden oluşturmak istemezsiniz.

// BUNU YAPMAreturn Consumer<CartModel>(  builder: (context, cart, child) {    return HumongousWidget(      // ...      child: AnotherMonstrousWidget(        // ...        child: Text('Total price: ${cart.totalPrice}'),      ),    );  },);
Enter fullscreen modeExit fullscreen mode

Bunun yerine:

// BUNU YAPreturn HumongousWidget(  // ...  child: AnotherMonstrousWidget(    // ...    child: Consumer<CartModel>(      builder: (context, cart, child) {        return Text('Total price: ${cart.totalPrice}');      },    ),  ),);
Enter fullscreen modeExit fullscreen mode

References:
https://docs.flutter.dev/development/data-and-backend/state-mgmt/simple
https://pub.dev/documentation/provider/latest/provider/Consumer-class.html
https://flutterbyexample.com/lesson/finer-build-control-with-selector-1

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

soft. dev. at harmonycloud
  • Location
    Sakarya, Türkiye
  • Education
    Pamukkale University
  • Work
    harmonyerp
  • Joined

More fromGülsen Keskin

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp