বিল্ড পদ্ধতি এমনভাবে এটি হওয়া উচিত এ ডিজাইন করা হয়েছে বিশুদ্ধ / পার্শ্ব প্রতিক্রিয়া ছাড়াই । এটি কারণ অনেকগুলি বাহ্যিক কারণ একটি নতুন উইজেট বিল্ডকে ট্রিগার করতে পারে, যেমন:
- রুট পপ / পুশ
- স্ক্রীন আকার পরিবর্তন, সাধারণত কীবোর্ড উপস্থিতি বা অভিমুখী পরিবর্তনের কারণে
- মূল উইজেট তার শিশুটিকে পুনরায় তৈরি করেছে
- একটি উত্তরাধিকারী উইজেট উইজেট (
Class.of(context)প্যাটার্ন) পরিবর্তনের উপর নির্ভর করে
এর অর্থ এই যে কোনও buildপদ্ধতিতে কোনও HTTP কল ট্রিগার করা বা কোনও রাজ্য সংশোধন করা উচিত নয় ।
এটি প্রশ্নের সাথে কীভাবে সম্পর্কিত?
আপনি যে সমস্যার মুখোমুখি হচ্ছেন তা হ'ল আপনার বিল্ড পদ্ধতির পার্শ্ব-প্রতিক্রিয়া রয়েছে / খাঁটি নয়, বহির্মুখী বিল্ড কলকে সমস্যাযুক্ত করে তোলে।
বিল্ড কল প্রতিরোধের পরিবর্তে, আপনার আপনার বিল্ড পদ্ধতিটি খাঁটি করা উচিত, যাতে এটি যে কোনও সময় প্রভাব ছাড়াই বলা যায়।
আপনার উদাহরণের ক্ষেত্রে, আপনি আপনার উইজেটটিকে StatefulWidgetতারপরে রূপান্তর করতে চান তারপরে সেই HTTP কলটি তার থেকে বের করে initStateনিন State:
class Example extends StatefulWidget {
@override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
Future<int> future;
@override
void initState() {
future = Future.value(42);
super.initState();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: future,
builder: (context, snapshot) {
// create some layout here
},
);
}
}
আমি এটি ইতিমধ্যে জানি। আমি এখানে এসেছি কারণ আমি সত্যিই পুনর্নির্মাণগুলি অনুকূল করতে চাই
বাচ্চাদের খুব বেশি জোর না করে পুনর্নির্মাণের পক্ষে উইজেট তৈরি করাও সম্ভব।
যখন কোনও উইজেটের উদাহরণ একই থাকে; উদ্দেশ্যমূলকভাবে বাজানো বাচ্চাদের পুনর্নির্মাণ করবে না। এর থেকে বোঝা যায় যে অপ্রয়োজনীয় পুনর্নির্মাণগুলি প্রতিরোধ করতে আপনি আপনার উইজেট গাছের কিছু অংশ ক্যাশে করতে পারেন।
সবচেয়ে সহজ উপায় ডার্ট constকন্সট্রাক্টরগুলি ব্যবহার করা :
@override
Widget build(BuildContext context) {
return const DecoratedBox(
decoration: BoxDecoration(),
child: Text("Hello World"),
);
}
এই constকীওয়ার্ডটির জন্য ধন্যবাদ , DecoratedBoxবিল্ডটি কয়েকবার বলা হলেও , উদাহরণটি একই থাকবে।
তবে আপনি নিজে নিজে একই ফলাফল অর্জন করতে পারেন:
@override
Widget build(BuildContext context) {
final subtree = MyWidget(
child: Text("Hello World")
);
return StreamBuilder<String>(
stream: stream,
initialData: "Foo",
builder: (context, snapshot) {
return Column(
children: <Widget>[
Text(snapshot.data),
subtree,
],
);
},
);
}
এই উদাহরণে যখন স্ট্রিমবিল্ডারকে নতুন মান সম্পর্কে অবহিত করা হয়, subtreeতখনও স্ট্রিমবিল্ডার / কলামটি পুনর্নির্মাণ করবে না। এটি ঘটেছিল কারণ, বন্ধ করার জন্য ধন্যবাদ, উদাহরণটি MyWidgetপরিবর্তিত হয়নি।
অ্যানিমেশনগুলিতে এই প্যাটার্নটি প্রচুর ব্যবহৃত হয়। সাধারণ ব্যবহারগুলি AnimatedBuilderএবং সমস্ত ট্রানজিশন যেমন AlignTransition।
আপনি subtreeহট-লোড বৈশিষ্ট্যটি ভাঙ্গার কারণে কম সুপারিশ করা হলেও আপনি আপনার শ্রেণীর কোনও ক্ষেত্রে এটি সঞ্চয় করতে পারেন ।