Flutter: FutureBuilder คืออะไร(ตัวสร้างอนาคต หรอ?)

Grassroot Engineer
2 min readDec 6, 2020

--

ในบทความนี้จะมาแนะนำเรื่อง Future Builder มันคืออะไร เกี่ยวอะไรกับอนาคต

https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

Future builder คือ ตัวช่วยในการ render widget เฉพาะในส่วนที่มีการเปลี่ยนแปลงเท่านั้น แปลว่าอะไร? กล่าวคือโดยปกติเนี่ยถ้ามีการเปลียนแปลงที่ UI เราจะทำการ setState() เพื่อให้ build() ทำงานแต่นั่นจะเป็นการ render ใหม่ทั้งหน้าเลย ซึ่งจะทำให้ performance ของ Appไม่ดีครับ

ต่อไปคือสิ่งที่จะ render จะมาจาก web api กล่าวคือ ยังไม่มีข้อมูลเดี๋ยวนั้น แต่ข้อมูลกำลังจะมาในอนาคต จึงเป็นที่มาของคำว่า Future นั่นเอง

วิธีการใช้งานนั้นง่ายมาก Widget ไหนที่เราต้องการให้ render ใหม่เฉพาะส่วน ให้ครบลงไปด้วย FutureBuilder

จริงๆแล้วในเรื่องนี้ เราสามารถนำ StreamBuilder()มาใช้แทน FutureBuilder() ได้เลยคือแทบจะทุกกรณี แต่ในบทความนี้จะใช้ FutureBuilder() ก่อนนะคับ เพราะเป็นการเรียก api ครั้งนึงต่อการ render ครั้งนึง

  1. เริ่มแรกเรามาสร้าง Future<String> method สำหรับ call webAPI ก่อนนะคับ โดยการ call API นี้แต่ละครั้งจะได้ cat url ที่ไม่เหมือนเดิม
https://api.thecatapi.com/v1/images/search // web api ที่ใช้นะคับ
สร้าง Function สำหรับ call api (คืนค่าออกมาเป็น Future และเรานำ .url ไปใช้งานนะคับ) และสร้าง model มารองรับ response ด้วย

2. ถัดไป ให้ลองสร้าง button ui ขึ้นมาสำหรับ call api ทุกครั้งที่มีการกดนะคับ

เมื่อมีการกด จะได้ url ใหม่ทุกครั้ง

3. สร้าง FutureBuilder ขึ้นมา โดยมีสิ่งสำคัญที่ต้องใช้ 2 อย่างคือ
- future: รับเป็น Future<dynamic>
- builder: เป็นตัวช่วยเพื่อแสดงสถานะต่างๆ เช่น ถ้าทำงานอยู่จะให้แสดงเป็น widget อะไร, ถ้ายังไม่ทำงานจะให้แสดงอะไร หรือ ถ้า error จะให้แสดงอะไร เป็นต้น

(โดยลอง return เป็น CircularProgressIndicator เพื่อไว้ใช้ระหว่างที่รอ response ก่อน)

FutureBuilder(  
future: getCatImage(),
builder:(BuildContext context, AsyncSnapshot<dynamic> snapshot) {
return CircularProgressIndicator();
},
)

4. ถัดไปที่ AsyncSnapshot เป็นตัวแทนสถานะการทำงานของ Future ที่ได้รับมาโดย type ที่กำหนดมาตอนนี้เป็น dynamic ให้เราปรับให้ตรงกับ type ที่ได้รับมานั่นคือ String นั่นเอง
(ถ้าไม่ตรงกัน อาจจะแสดงผลไม่ได้ เพราะ Future<String> ไม่ใช่ subtype ของ type Strint นะคับ)

builder:(BuildContext context, AsyncSnapshot<String> snapshot)

จากนั้นเราก้อนำ snapshot มาใช้งานได้เลยดังนี้

การนำ snapshot มาใช้งาน ตอนนี้ยังเทียบแค่ 2 แบบคือ done และ CircularProgressIndicator()

5. ลองปรับให้ return เป็น Image.network ก้อจะแสดงเป็นรูปภาพแทนแล้วนะคับ แต่ถ้าจะลองเปลี่ยนจาก if statement เป็น switch case ก็สามารถทำได้เช่นกันคับ

เปรียบเทียบ return ต่างๆของ snapshot (snapshot เป็นตัวบอกสถานะต่างๆของ State ว่าเป็นยังไง)
User interface

Fullcode:

test_futurebuilder.dart

Model file:

cat_model.dart

ps: ในกรณีที่ข้อมูลเราเปลี่ยนแปลงแค่ครั้งเดียว เช่น ถ้ากดปุ่มก้อจะ call API แค่ครั้งเดียว ในกรณีแบบนี้เราจะใช้ FutureBuilder

แต่ถ้าต้องมีการ call API แบบต่อเนื่องเพื่อเปลี่ยนแปลงข้อมูลไปได้เรื่อยๆ เราจะใช้ StreamBuilder แทนนะ

--

--

Grassroot Engineer
Grassroot Engineer

Written by Grassroot Engineer

ATM engineer who is interested in CODING and believe in EFFORT. — https://grassrootengineer.com

No responses yet