ทำความเข้าใจวงจรชีวิตของ Flutter Widget เพื่อการพัฒนาแอพอย่างมีประสิทธิภาพ

กล่าวโดยทั่วๆ ไป วัฏจักรชีวิตแสดงถึงระยะตั้งแต่การสร้างจนถึงการถูกทำลาย ในบริบทของ flutter ก็เช่นเดียวกัน วันนี้เราจะพูดถึงวงจรชีวิตของวิดเจ็ต (อย่าสับสนกับวงจรชีวิตของแอพ)
ในฐานะนักพัฒนา Flutter เราควรใช้วิธีวงจรชีวิตเหล่านั้นอย่างไรเป็นจุดประสงค์หลักของบทความนี้ ดังนั้นเรามาเข้าสู่ส่วนที่สนุกกันดีกว่า
สร้างสถานะ ()
เมื่อเราสร้างวิดเจ็ต stateful ใน Flutter createState
เมธอดจะถูกเรียกทันทีเพื่อส่งคืนอินสแตนซ์สถานะของคลาสที่เกี่ยวข้อง
นี่เป็นสิ่งสำคัญเพราะใน Flutter ทุกสิ่งจะเปลี่ยนแปลงไม่ได้ (รวมถึงวิดเจ็ตที่มีสถานะ) สิ่งสำคัญคือต้องแยกงานที่ไม่แน่นอนและมอบหมายงานให้กับคลาสสถานะ ด้วยวิธีนี้ Flutter สามารถทำให้คลาสที่ไม่เปลี่ยนรูปดูและทำงานเหมือนกับคลาสที่ไม่เปลี่ยนรูป และเราสามารถเห็นการเปลี่ยนแปลงทั้งหมดใน UI
สิ่งนี้ยังมีประโยชน์ด้านประสิทธิภาพ เนื่องจาก Flutter สามารถเปลี่ยนตัวแปรสถานะและสะท้อนการเปลี่ยนแปลงในลักษณะที่เหมาะสมได้ง่ายกว่าการสร้างแผนผังวิดเจ็ตใหม่ทั้งหมดเนื่องจากการเปลี่ยนแปลงเพียงเล็กน้อย
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => new _HomePageState();
}
นี่เป็นวิธีแรกที่เรียกว่าการสร้างสถานะหลัง และเรียกเพียงครั้งเดียวเท่านั้น
วิธีนี้สามารถใช้เพื่อ:
- เริ่มต้นตัวแปรปลาย
- สมัครสมาชิกเพื่อสตรีม ฯลฯ
@override
initState() {
super.initState();
_controller=TextEditingController();
myStream.listen((data) {});
}
ดังนั้นการพึ่งพาอาศัยกันคืออะไร?
สมมติว่าเราใช้ MediaQuery.ofในวิดเจ็ต เราสามารถพูดได้ว่าวิดเจ็ตของเราขึ้นอยู่กับ MediaQuery ดังนั้นเมื่อใดก็ตามที่ MediaQueryอัปเดตวิธีนี้จะถูกเรียกใช้
ดังนั้นเราจึงบอกได้ว่าวิดเจ็ตของเราขึ้นอยู่กับInherited Widget
(คิวรีสื่อ ธีม ผู้ให้บริการ ฯลฯ) หรือไม่ และเมื่อใดก็ตามที่วิดเจ็ตที่สืบทอดมาเหล่านั้นพุชอัปเดต วิดเจ็ตจะทริกเกอร์วิธีนี้
หลังจากbuild()
เมธอดนี้จะถูกเรียกใช้ ดังนั้นในฐานะนักพัฒนาจึงไม่มีสถานการณ์มากมายที่เราอาจต้องใช้ตรรกะที่กำหนดเองที่นี่ แต่ตามเอกสารอย่างเป็นทางการระบุว่า
เพื่อทำงานบางอย่างที่มีราคาแพง (เช่น การดึงข้อมูลจากเครือข่าย) เมื่อการพึ่งพาเปลี่ยนแปลง และงานนั้นจะแพงเกินไปสำหรับทุกบิลด์
ตัวอย่างเช่น: Inherited Widget
คุณอาจได้รับค่าบางอย่างจากคุณและจำเป็นต้องดำเนินการบางอย่างที่มีราคาแพงตามค่านั้นและแสดงใน UI คุณอาจไม่ต้องการทำเช่นนี้ในวิธีการสร้าง ดังนั้นdidChangeDependencies
จะเป็นจุดที่สมบูรณ์แบบสำหรับสิ่งนี้
didUpdateWidget
ลองมาดูตัวอย่างเพื่อทำความเข้าใจสิ่งนี้ คุณมีContainer
สีแดงและแตะปุ่มเปลี่ยนเป็นสีน้ำเงิน
ที่นี่ทั้งอินสแตนซ์วัตถุเก่าและใหม่เป็นประเภทเดียวกันruntimeType
แต่ข้อมูลแตกต่างกันดังนั้นในกรณีนี้วิธีนี้จะถูกทริกเกอร์ มันได้รับวิดเจ็ตเก่าdidUpdateWidget(Widget oldWidget)
ด้วย
@override
void didUpdateWidget(Widget oldWidget) {
if (oldWidget.color != widget.color) {
/// Your logic
}
}
- สถานการณ์หนึ่งที่เป็นไปได้สามารถนำมาใช้ในแอนิเมชั่นเพื่อเปลี่ยนระหว่างค่าต่างๆ
- อีกกรณีหนึ่งอาจเป็นกรณีการใช้งานเฉพาะตามความต้องการของแอปของคุณ โดยอิงจากค่าวิดเจ็ตใหม่ที่ทำงานที่แตกต่างกัน เช่น สมัครรับข้อมูลสตรีมใหม่และยกเลิกการสมัครรับข้อมูลสตรีมก่อนหน้า
สร้าง()
นี่เป็นวิธีการสำคัญที่ในฐานะโปรแกรมเมอร์ เราต้องส่งคืนวิดเจ็ตที่เราต้องการแสดงแก่ผู้ใช้
นอกจากนี้ วิธีการนี้สามารถเรียกใช้ได้หลายครั้ง ดังนั้นจึงไม่ใช่วิธีปฏิบัติที่ดีในการดำเนินการที่มีราคาแพงภายในวิธีนี้
สามารถเรียกใช้เมธอดของเขาได้ในทุกๆ เฟรม และไม่ควรมีผลข้างเคียงใดๆ นอกเหนือจากการสร้างวิดเจ็ต
setState((){})
setState((){}) เป็นเมธอดที่ใช้เมธอดเป็นพารามิเตอร์และเรียกใช้markNeedsBuild()
เมธอดภายในเพื่อทริกเกอร์บิลด์ใหม่
/// Implementation of setState() in flutter
@protected
void setState(VoidCallback fn) {
final Object? result = fn() as dynamic;
_element!.markNeedsBuild();
}
- เราไม่ควรส่งฟังก์ชัน async ไปยัง setState เนื่องจากภายในจะไม่รอการแก้ไขในอนาคต ดังนั้นเราจะไม่เห็นการสะท้อน UI ที่ต้องการ
setState(() {
/// New State values
color=Colors.red;
});
dispose() เมธอดถูกเรียกเมื่อวัตถุสถานะถูกลบออก นี่เป็นวิธีสุดท้ายที่จะถูกกระตุ้นในวงจรชีวิต
ในฐานะนักพัฒนา เราสามารถ:
- ยกเลิกการสมัครสตรีม
- กำจัดตัวควบคุม
- หยุดภาพเคลื่อนไหว เป็นต้น
เนื่องจากวิดเจ็ตไร้สัญชาติไม่มีสถานะที่เปลี่ยนแปลงได้ (สังเกตได้จากชื่อ) วิธีการวงจรชีวิตบางอย่าง เช่นinitState
และdispose
อื่น ๆ จึงขาดหายไปที่นี่
แหล่งที่มา:
https://www.youtube.com/watch?v=_gIbneld-bw
https://api.flutter.dev/index.html