Home Coding การใช้ Get ใน Flutter , Package ที่เรียกตัวเองว่า Microframework

การใช้ Get ใน Flutter , Package ที่เรียกตัวเองว่า Microframework

by khomkrit
set of tool wrench
Photo by Pixabay on Pexels.com

Get เรียกตัวเองว่าเป็น Microframework ทำหน้าที่ 2 อย่างคือเป็น state management กับเป็น utility package ซึ่งมีเครื่องมือต่างๆ มาให้เราใช้จำนวนมาก ดังนั้นก็ไม่แปลกที่ การใช้ Get ใน Flutter นั้นได้ช่วยให้เราจัดการสิ่งต่างๆ ได้อย่างง่ายดาย

เวลาเราพัฒนาแอปใน Flutter ก็มักมีท่านึงที่ถูกใช้บ่อยๆ ก็คือเราจะสร้าง instance ที่มีเพียงตัวเดียวในแอป แล้วก็แชร์ข้อมูลนี้ทั่วทั้งแอป โดยที่เวลาใช้ก็สามารถอ้างตัว instance ตัวนี้มาใช้ได้เลยจากที่ไหนก็ได้ในแอป ถ้าทำโดยใช้ท่ามาตรฐานตามเอกสารอย่างเป็นทางการของ Flutter เลยก็คือใช้ Provider ที่เป็นหนึ่งใน Flutter Favorite package

Flutter Favorite
Flutter Favorite

ตัวอย่างก็เช่น object ที่เอาไว้เก็บ User info และใช้ร่วมกับ login / logout อะไรพวกนี้ ที่เราจะสร้าง instance ของ user ขึ้นมา 1 ตัวเอาไว้เก็บ user profile แล้วเราก็ทำให้เราสามารถเรียกใช้มันจากไหนก็ได้เพื่อเข้าถึง User profile

Get is a microframework, not just a state manager

get

Get ไม่ใช่แค่ state manager แต่มันคือ  microframework (เขาเรียกตัวเองแบบนี้) ลองมาดู Get ในฐานะ state manager กับแอปง่ายๆ อย่าง counter app ก่อน

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp(GetMaterialApp(home: Home()));
}

class Counter extends ให้ {
  var count = 0.obs;
  increment() => count++;
}

class Home extends StatelessWidget {
  final counter = Get.put(Counter());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Obx( () => Text(counter.count.toString())),
          RaisedButton(child: Text('Click Me'), onPressed: counter.increment)
        ],
      )),
    );
  }
}

จากโค้ด จะเห็นว่าเราใช้ GetMaterialApp แทน MaterialApp แต่ก็ไม่ได้หมายความว่าเราไม่ได้ใช้ MaterialApp แบบที่เคยใช้กัน เพราะจริงๆ แล้ว GetMaterialApp เพียงแต่เข้าไป pre-configure บางอย่างให้เราก่อนเท่านั้น แล้วก็ยังให้ MaterialApp เป็น child ตามเดิม

หลักๆ แล้ว GetMaterialApp จะเข้าไปจัดการสิ่งต่างๆ เกี่ยวกับพวก routes, snackbars, internationalization, bottomSheets, dialogs และ high-level api ต่างๆ ที่เกี่ยวข้องกับ routes เท่านั้น แปลว่า ถ้าเราจะใช้ Get แค่ state management หรือ dependency injection เท่านั้น เราก็ไม่จำเป็นต้องใช้ GetMaterialApp ก็ได้

ส่วนโค้ดข้างในนั้นหมายความว่าอะไร จะอธิบายหลังจากนี้ ต่อไปเรามาดูเรื่อง routes กันต่อ

สร้างหน้าที่ 2 ขึ้นมา ดังนี้

class Second extends StatelessWidget {
  final Counter counter = Get.find();
  @override
  Widget build(context) {
    return Scaffold(
      appBar: AppBar(title: Text('Second')),
      body: Center(child: Text("${counter.count}"))
    );
  }
}

ในหน้านี้เราจะอ้างถึง counter ตัวเดียวกับหน้าแรก ได้จาก Get.find(); และเอาค่า count ที่อ่านได้มาแสดงไว้กลางจอเพื่อพิสูจน์ว่าดึงค่ามาจาก object ตัวเดียวกันนะ

แล้วเราก็กลับมาแก้ที่หน้า Home โดยการเพิ่มปุ่มที่กดแล้วให้มันแสดงหน้าที่สอง ดังนี้

RaisedButton(child: Text('Go Second'), onPressed: () => Get.to(Second()))

เท่านี้เมื่อเรากดปุ่มมันก็เปลี่ยนหน้าแล้ว เราแค่บอกไปเลยตรงๆ ว่าให้ไปที่หน้า Second เท่านั้น แล้ว Get ก็ทำให้

สามเสาหลักของ Get

State Management

แม้แต่ Provider เองที่เว็บไซต์อย่างเป็นทางการของ Flutter แนะนำให้เราใช้ก็ยังใช้ ChangeNotifier ทำงานอยู่เบื้องหลัง ซึ่งในหน้าเพจของ Get เองได้อ้างว่าเอกสารของ Flutter เองก็บอกอีกว่าการใช้ ChangeNotifier นั้นควรใช้กับ listener แค่ 1 ถึง 2 ตัวเท่านั้น (ตอนนี้เข้าไปหาดูไม่เจอแล้ว) ดังนั้น Provider จึงไม่น่าจะเหมาะกับแอปขนาดกลางถึงขนาดใหญ่

มาถึงตอนนี้ก็อย่างที่บอกไป คือมันเป็น micro framework ไม่ใช่แค่ state management แปลว่าเราจะเลือกใช้เพียงอย่างใดอย่างหนึ่งก็ได้ แล้วแต่ความเหมาะสม

Reactive programming นับเป็นยาขมสำหรับ programmer หลายๆ คนเลย หลายคนบอกว่า งง ซึ่งมันก็ งง จริงๆ 😅 แต่ Get ทำให้เราใช้ Reactive programming ได้ในท่าที่ง่ายๆ อย่างน้อยเราก็เอาไปพูดให้ dev คนอื่นฟังว่าเราก็ใช้ได้พอไม่ขัดเขิน

เช่น เรามีตัวแปรแบบนี้

var count = 0.obs;

หากเราต้องการกำหนดว่า เมื่อค่าในตัวแปรนี้เปลี่ยนให้มาบอกเราด้วย เราก็จะใส่ .obs ต่อท้ายตัวแปรลงไปแบบนี้

var count = 0.obs;

ถ้าเราเอาค่าในตัวแปรนี้ไปแสดงใน GUI ก็ทำแบบนี้ แล้วเราก็จะได้ Text ที่อัพเดทตัวเองอยู่เสมอตามค่าใน attribute count

Obx(() => Text("${counter.count}"));

Route management

อย่างที่บอกไปว่ามันเป็น microframework ก็เลยทำให้เราสามารถจัดสิ่งๆ ต่างๆ ในแอปได้อย่างง่ายดาย ยกตัวอย่างเช่นการจัดการ route เมื่อเราต้องการเปลี่ยน route ก็ใช้ฟังก์ชั่นนี้

Get.to(NextScreen());

หรือจะปิด Snackbar, dialogs, bottom sheet, หรืออื่นๆ ที่ปกติเราต้องปิดมันด้วยคำสั่ง Navigator.pop(context); เมื่อเรามี Get เราก็จะเปลี่ยนมาใช้

Get.back();

หรือถ้าอยากจะแสดงหน้าถัดไปแต่ไม่ให้แสดงปุ่ม back เช่น เมื่อ user กด logout แล้วเราต้องการแสดงหน้า login เราก็ใช้แบบนี้

Get.off(NextScreen());

หรือจะแสดงหน้าถัดไปและยกเลิกทุกๆ route ที่เคยเปิดมา Get ก็ทำให้เรา

Get.offAll(NextScreen());

จะเห็นว่าเราไม่ต้องไปยุ่งอะไรกับ context แล้ว เพราะ Get ทำให้ เราแล้วตั้งแต่ขั้นตอนการ pre-configure

Dependency Management

แทนที่เราจะสร้าง object ของ Counter ขึ้นมาเองตรงๆ เราก็สร้างมันโดยใช้ Get เพื่อที่จะทำให้เราสามารถอ้างถึง counter ในแอปจากที่ไหนก็ได้

const Counter counter = Get.put(Counter());
...
counter.increment();

ตอนอ้างถึง counter

Counter counter = Get.find();

พอได้ reference มาแล้ว เราสามารถเอา counter ไปใช้งานได้เลยตรงๆ แบบนี้

Text("${counter.count}"

นอกจากนี้ Get ยังมี Utils ต่างๆ ให้ใช้อีกมาก ลองไปตามต่อกันได้ที่ get | Flutter Package

การพัฒนาแอปด้วย Flutter นั้นหลายอย่างค่อนข้างเรียบง่าย ตั้งแต่การกำหนดให้ flutter รันแยก environment ได้ แล้วยังมีเรื่อง state management กับ utils ต่างๆ ที่ Get ทำมาให้เราใช้อีก หวังว่า การใช้ Get ใน Flutter นั้นจะทำให้เราทำแอปได้รวดเร็วขึ้นไปอีกขั้น

มาถึงตรงนี้คงไม่ต้องอธิบายโค้ดที่ยกมาตอนแรกแล้ว ว่ามันทำงานยังไง

You may also like

1 comment

Comments are closed.