Flutter efficient state-management with flutter_riverpod

Tech Talk

by Engineers of Acroquest Myanmar Technology

Flutter efficient state-management with flutter_riverpod

Go to English summary >>

အားလုံးပဲ မင်္ဂလာပါ။

ကျွန်တော်နာမည်က ထက်နောင်နောင် ပါ။ ကျွန်တော်ကတော့ Senior Software Engineer တစ်ယောက် အနေနဲ့ Acroquest Myanmar Technology မှာ အလုပ်လုပ်ကိုင်လျှက်ရှိပါတယ်။ 
ပထမဦးဆုံးအနေနဲ့ Flutterကို စတင်လေ့လာနေသူများအတွက် Flutter ကဘာလဲဆိုတာကို ရှင်းပြပေးပါမယ်။  

◆ Flutter ဆိုတာဘာလဲ

Flutter ကcodebase တစ်ခုတည်းမှ Android, iOS, Windows, Linux and Web စတဲ့ multi-platform တွေမှာ applications များတည်ဆောက်ရန်အတွက် Google ကထုတ်ထားတဲ့ open-source framework တစ်ခုဖြစ်ပါတယ်။ 
https://flutter.dev/

Flutter ကို အသုံးပြုခြင်းဖြင့် အောက်ပါ အကျိုးကျေးဇူးများကို ရရှိနိုင်ပါတယ်။  

  1. Platforms အားလုံးမှာ တူညီသော UI နှင့် Business Logic အသုံးပြုနိုင်ခြင်း။ 
  2. Codeတွေကို မြန်မြန်ရေးနိုင်ခြင်း။ 
  3. Development Time ကိုလျှော့ချနိုင်ခြင်း။ 
  4. Market ကိုမြန်မြန်ပို့ပေးနိုင်ခြင်း။ 

Flutter ရဲ့အကျိုးကျေးဇူးတွေကို သိရှိပြီးပြီဆိုတော့ Flutter ကို အသုံးပြုပြီး application တစ်ခုကို ဘယ်လိုတည်ဆောက်နိုင်လဲဆိုတာကို လေ့လာနိုင်ပါတယ်။ အထက်ဖော်ပြပါ application creation ကို လေ့လာပါက အောက်ပါရလဒ်ကို ရရှိပါမယ်။ 

◆ Flutter State

Flutter မှာ Stateful and Stateless widgets ဟူ၍နှစ်မျိုးရှိပါတယ်။ Stateless widget က State တွေမပါဘဲ UI ပြဖို့အတွက်ပဲအဓိကသုံးပါတယ်။ Stateful widget ကတော့ State တွေအပြောင်းအလဲပေါ်မူတည်ပြီးတော့ UI ကိုပြဖို့အတွက်သုံးပါတယ်။ ဥပမာအားဖြင့် Stateful widgetမှာ State တွေအပြောင်းအလဲလုပ်ချင်တယ်ဆိုပါက အောက်ပါအတိုင်းပြုလုပ်နိုင်ပါတယ်။ 

setState(() { 
  /// to change the state 
  _counter++; 
});  

◆ flutter_riverpod ဆိုတာဘာလဲ

ကျွန်တော့်အတွေ့အကြုံအရ flutter_riverpod ဟာ တခြားသော state-management library တွေထက် project တစ်ခုလုံးမှာ ရှိတဲ့ state တွေကို ပိုမိုလွယ်ကူစွာ management လုပ်ပေးနိုင်ပါတယ်။   

အခု Flutterရဲ့ state-management library တစ်ခုဖြစ်တဲ့ flutter_riverpod အကြောင်းကို ပြောပြပေးမှာဖြစ်ပါတယ်။

flutter_riverpod ဆိုတာ Flutter ရဲ့ state ကိုပိုမိုလွယ်ကူစွာ management လုပ်ပေးနိုင်တဲ့ state-management library တစ်ခုဖြစ်ပါတယ်။ 

ဥပမာအားဖြင့် Widget1၊ Widget2 နှင့် Widget3 ဟူ၍ Widgetသုံးခုရှိပါတယ်။ သူတို့ရဲ့ relation က Widget1(Parent), Widget2(Child) နှင့် Widget3(Grandchild) တို့ဖြစ်ပါတယ်။ Widget3(Grandchild) က Widget1(Parent) ရဲ့ state ကိုအပြောင်းအလဲလုပ်ချင်တယ်ဆိုပါစို့ 

flutter_riverpod ကို မသုံးရင် InheritedWidget ကိုအသုံးပြုရန်လိုအပ်ပြီး coding က ရှုပ်ထွေးလာပြီး maintenance ပြုလုပ်ရန် ခက်ခဲလာမယ်ဖြစ်ပါတယ်။ အကယ်၍ flutter_riverpod ကို အသုံးပြုပါက ‘Provider’ သို့မဟုတ် ‘Controller’ ကို အသုံးပြု၍ အလွယ်တကူ state တွေ ကို အပြောင်းအလဲလုပ်နိုင်ပါတယ်။
 
flutter_riverpod ကို အသုံးပြုခြင်းဖြင့် အောက်ပါ အကျိုးကျေးဇူးများကို ရရှိနိုင်ပါတယ်။ 

  1. runtime မှာမဟုတ်ဘဲ compile time တွင် programming error များကိုဖမ်းနိုင်ပါတယ်။
  2. Object တွေကို ထပ်ခါထပ်ခါ listening/combining လုပ်စရာမလိုအောင်ကူညီပေးပါတယ်။ 
  3. Code တွေရဲ့ testability ကိုပိုမိုကောင်းမွန်စေပါတယ်။

flutter_riverpod ကိုအသုံးပြုခြင်းအားဖြင့် development ၊ maintenance နှင့် testing အတွက် အချိန်အသုံးပြုမှုကို လျှော့ချနိုင်ပါတယ်။ 

■ Sample application ဖန်တီးခြင်း

ဥပမာတစ်ခုအနေနဲ့ Counter App နဲ့ ပြောပြပေးပါမယ်။ ကျွန်တော် မှာတော့ flutter project တစ်ခု ရှိနှင့်ပြီးသား ဖြစ်ပါတယ်။

Project ကို create လုပ်တဲ့အကြောင်း သိလိုပါက အထက်မှာဖော်ပြထားသောlink တွင် လေ့လာနိုင်ပါတယ်။ 

Counter app ဆိုတာက ‘+’ icon ကို နှိပ်ပါက number တစ်ခုပြီးတစ်ခု တိုးလာမည်ဖြစ်ပါတယ်။ ဒီဥပမာလေးမှာ အဓိကအားဖြင့် state တွေကို ဘယ်လို read မယ်၊ ဘယ်လို manage လုပ်မယ်ဆိုတာကို ပြပေးမှာဖြစ်ပါတယ်။ 

■ pubspec.yaml တွင် dependencies ထည့်ခြင်း

ပထမဦးစွာ project တွင် flutter_riverpod plugin ကို install ရပါတယ်။ Project ၏ pubspec.yaml တွင် အောက်ပါ source code ကို ထည့်ပါ။ 

 dependencies: 
  flutter_riverpod: ^1.0.3  

ထို့နောက် command line တွင် အောက်ပါ coding ကို run ပါ။ 

 dart pub get 

or

 flutter pub get 

■ Projectတစ်ခုလုံးအတွက် Provider Scope ထည့်ခြင်း

Project ၏ ‘main.dart’ file တွင် အောက်ပါ ‘coding’ ကို ထည့်ပါ။

 import 'package:flutter_riverpod/flutter_riverpod.dart'; 

Project တစ်ခုလုံးအတွက် Provider Scope ကို ထည့်ပါ။

void main() { 
  runApp( 
    const ProviderScope(child: MyApp()), 
  ); 
}  

■ State Controller ဖန်တီးခြင်း

ပြီးရင် ကျွန်တော်တို့ state တွေကို management လုပ်ဖို့ controller (provider) တစ်ခု create လုပ်ပါမယ်။ ‘+’ icon ကို နှိပ်ရင် number တိုးသွားဖို့ အတွက် Controller မှာ increaseCount function ကို implementation လုပ်ပါတယ်။ 

final counterController = StateNotifierProvider((ref) { 
  return Counter(); 
}); 
 
class Counter extends StateNotifier<int> { 
  Counter() : super(0); 
 
  void increaseCount() => state++; 
}  

■ UI (User Interface) တည်ဆောက်ခြင်း

ကျွန်တော်တို့ UI မှာ နှစ် ခုလုပ်ပါမယ်။

  1. ပြောင်းလဲနေတဲ့ count တန်ဖိုးကို ပြပါမယ်။
  2. ‘+’ icon နှိပ်ရင် number တိုးဖို့အတွက် increaseCount function ကို ခေါ်ပါမယ်။
 

// read and listen for count state changes 
final count = ref.watch(counterController);  

ပြီးရင် increaseCount function ကို ခေါ်လို့ရအောင် controller instance ကို create လုပ်ပါမယ်။ 

// creating instance for the provider 
final controller = ref.read(counterController.notifier); 

ဒါကတော့ UI အတွက် Complete source codeပါ။ 

class MyHomePage extends ConsumerWidget { 
  final String title; 
  const MyHomePage({Key? key, required this.title}) : super(key: key); 
   
  // In here, we got extra argument [WidgetRef ref].  
  //We can use 'ref' for reading and managing the state. 
  @override 
  Widget build(BuildContext context, WidgetRef ref) { 
 
    // read and listen for count state changes 
    final count = ref.watch(counterController); 
 
    // creating instance for the provider 
    final controller = ref.read(counterController.notifier); 
    return Scaffold( 
      appBar: AppBar( 
        title: Text(title), 
      ), 
      body: Center( 
        child: Column( 
          mainAxisAlignment: MainAxisAlignment.center, 
          children: <Widget>[ 
            const Text( 
              'You have pushed the button this many times:', 
            ), 
            Text( 
              count.toString(), // counter count will be shown in here 
              style: Theme.of(context).textTheme.headline4, 
            ), 
          ], 
        ), 
      ), 
      floatingActionButton: FloatingActionButton( 
        // increaseCount function will be called when user click '+' icon button 
        onPressed: controller.increaseCount, 
        tooltip: 'Increment', 
        child: const Icon(Icons.add), 
      ), 
    ); 
  } 
}  

flutter_riverpod ရဲ့  ConsumerWidget ကို extend လုပ်ပြီး ကျွန်တော်တို့ build method မှာ extra WidgetRef argument ရပြီးတော့ provider ကို handling လုပ်နိုင်မှာပါ။ 

flutter_riverpod နဲ့ပတ်သက်ပြီး  အသေးစိတ်လေ့လာလိုပါက အောက်ပါ Link မှာသွားရောက်လေ့လာနိုင်ပါတယ်။
https://pub.dev/packages/flutter_riverpod

ဒီအ‌ကြောင်းအရာလေးကိုဖတ်ပြီး enjoyဖြစ်လိမ့်မယ်ထင်ပါတယ်။ စာဖတ်သူတို့လည်း projectမှာ ပြန်လည် အသုံးချနိုင်ဖို့မျှော်လင့်ပါတယ်။ 
နောက်လာမယ့်topicတွေလည်း စောင့်မျှော်ကြပါဦး။ (^^) 

[ English Summary ]

Hello, everyone. 
My name is Htet Naung Naung. I am working as a senior software engineer in Acroquest Myanmar Technology. 

Firstly, I would like to introduce what Flutter for beginners is. 

◆ What is Flutter?

Flutter is an open source framework developed by Google for building applications on multi-platforms such as Android, iOS, Windows, Linux and Web from a single codebase. 

By using Flutter, we can get the following advantages 

  1. Same UI and business login in all platforms 
  2. Faster code writing
  3. Reduced code development time 
  4. Increased time to market speed. 

After learning about Flutter’s advantages, you can learn how to build an application by using Flutter. 

◆ Flutter State

Flutter has two types of widgets: Stateful and Stateless. The Stateless widget is mainly used to display the UI without the states. The Stateful widget is used to display the UI, depending on how the states change. 

◆ What is flutter_riverpod?

According to my experience, flutter_riverpod makes easier to manage sates throughout the project than any other state-management libraries.  Now, I would like to introduce flutter_riverpod, one of Flutter’s state-management libraries for beginners to Flutter.  

flutter_riverpod is a state-management library that makes it easier to manage Flutter state. 
For example, there are three widgets: Widge1, Widget2 and Widget3. Their relations are Widget1 (Parent), Widget2 (Child) and Widget3 (Grandchild).
Suppose that Widget3 (Grandchild) wants to change the state of Widget1 (Parent) :

  • If you do not use flutter_riverpod, you will need to use InheritedWidget, and the coding will be complicated and difficult to maintain.
  • If you use flutter_riverpod, you can easily change states using ‘Provider’ or ‘Controller’.

By using flutter_riverpod, we can get the following advantages 

  1. catches programming errors at compile time rather than at runtime
  2. removes nesting for listening/combining objects 
  3. increases the testability of application 

We can reduce the time usage for development, maintenance and testing by using flutter_riverpod.  If you want to know more about flutter_riverpod, you can visit the following  
https://pub.dev/packages/flutter_riverpod 

I hope you enjoy reading this article. Readers are also encouraged to apply it to the project. Stay tuned for more topics. (^^) 

★★★We are hiring the staff who are interested in latest technologies.★★★

If you are interested in our company, please see the available job descriptions in the following links.

Senior Software Developer: https://www.acromyanmar.com/senior-software-developer/
Intermediate Software Developer: https://www.acromyanmar.com/intermediate-software-developer/


Check our Facebook Page!