Software development company
11 05 2020
เป็น state management ที่เอาตัว InheritedWidget มาทำให้ง่ายขึ้น
ก่อนอื่นจะขอเกริ่นเรื่อง state management ก่อนอื่น
state management คืออะไร state management คือ ก็ตรงตามชื่อแหละครับ ตัวจัดการ state พูดธรรมดาอาจไม่เข้าใจ เดี๋ยวขอยกตัวอย่างให้ฟังครับ ถ้าสมมัติเราได้ทำแอปที่ให้มาก ๆ สมมุติว่าเป็นประมาณนี้
ถ้าสมมติเราต้องการจะส่งข้อมูลไปที่ battombar โอเคมันก็จะเป็นประมาณนี้
แค่คิดก็ยุ่งยากละ แล้วในเรื่องจริงมันไม่ได้มีแค่นี้ด้วย
ทีนี้ถ้าเป็น provider หละ มันก็จะเหมือนมีตัว Global Variable (มันก็ไม่ได้ Global เลยทีเดียวเพราะมันมีเรื่อง Scope อีก) อยู่ตอนเปลี่ยนค่ามันก็จะอ้างไปที่ค่านั่นทุก ๆ เราก็ยิงตรงเข้าตัว Provider นั่นเลย
ทีนี้มาพูดถึงเรื่อง provider กับ scope กันก่อน
โครงสร้างตัว flutter มันเป็น Tree ใช่ครับ ( อารมณ์ประมาณ DOM ใน HTML ) คือในการใช้ provider ต้องกำหนด Scope ก่อนคือกำหนดให้ว่าเราจะใช้ provider ตัวนี้ใช้ได้ตรงไหนบ้าง คือตัว Children node มันใช้ใช้ได้หมดเลย ข้างนอกจะใช้ไม่ได้
Okay มาเริ่มเขียนโค้ดกันเลย ก่อนเพิ่ม Provider ใน puspec.yaml ก่อน
dependencies:
provider: ^4.1.1
ทีนี้ เพิ่ม provider และก็เพิ่ม class model ที่เก็บและจัดการ logic
จะเห็นว่า text จะแสดงถูกต้องแล้ว แต่ตอนกดปุ่ม Text มันไม่เปลี่ยนเป็น whenTab ตามที่เขียนไว้นะ console ก็ log ค่าออกมาถูกต้องแล้วแต่ UI มันจะไม่ rebuild ใหม่ มันก็จะเหมือน setState แหละต้องสั่งให้มัน rebuild ใหม่ และทีนี้ตัว Provider ต้องเปลี่ยนเปลี่ยนเป็นตัวใหม่ เป็นนน ChangeNotifierProvider และ ตัว class model ต้องสืบทอดตัว ChangeNotifier เข้ามา ทีนี้ตอน setState เปลี่ยนเป็นตัว notifyListeners(); widget ที่อยู่ในตัว consumer มันก็จะ rebuild ให้แล้ว
ทีนี้ตอนกด widget มันก็ rebuild แล้วอ่าาาาาา ง่ายใช่ไหมล้า
แต่ทีนี้ถ้าสังเกตทุก ๆ ครั้งที่เรากดปุ่ม widget ที่อยู่ในตัว consumer มัน rebuild จริง ๆ
ตัวปุ่มที่เราไม่อยากให้มัน rebuild หละเพราะไม่รู้จะทำทำไมเพราะ UI มันก็เหมือนเดิม แก้เป็นแบบนี้ซะ
อ่าาา~~ ทีนี้ตัวปุ่มมันก็ไม่ rebuild ให้แล้ว งะงะง่ายเกินไปแล้ว จริง ๆ มันมีอะไรเยอะกว่านั้นมากใน ตอนนี้ก็สามารถเอาไปประยุคเพิ่มในแอปของเราได้แล้วเจอกันตอนไหน้านะครับ
------------------------------------------------------------------------------------------------------------------------------------------------------
update ใหม่
เราสามารถเอา context มาใช้ได้ด้วยแบบไม่ต้องเอา Consumer ครอบเช่น
context.read<MyProvider>().onTab(); -> สั่งกด onTab
context.watch<MyProvider>().text, -> อ่านค่า text
The easiest way to read a value is by using the extension methods on [BuildContext]:
context.watch<T>()
, which makes the widget listen to changes on T
context.read<T>()
, which returns T
without listening to itcontext.select<T, R>(R cb(T value))
, which allows a widget to listen to only a small part of T
.ตัวอย่าง