setState() Flutter-এ State-এর মূল পদ্ধতি, যা ফ্রেমওয়ার্ককে ডেটা পরিবর্তন সম্পর্কে জানায় এবং ইন্টারফেস পুনর্নির্মাণ শুরু করে। অফিসিয়াল Flutter ডকুমেন্টেশন (Flutter.dev, 2026) অনুযায়ী, setState StatefulWidget-এ প্রধান প্রতিক্রিয়াশীলতা প্রক্রিয়া: এটি কল না করলে, UI State ফিল্ডের পরিবর্তন সম্পর্কে জানতে পারবে না এবং পূর্বের অবস্থায় থাকবে। পদ্ধতিটি একটি VoidCallback গ্রহণ করে, যার ভিতরে ডেভেলপার পরিবর্তনযোগ্য ফিল্ড পরিবর্তন করে, তারপর Flutter স্বয়ংক্রিয়ভাবে উইজেট পুনর্নির্মাণের জন্য build কল করে।
মূল বিষয়
setState() Flutter-এ State ক্লাসের একটি অন্তর্নির্মিত পদ্ধতি, যা ফ্রেমওয়ার্ককে জানানোর জন্য ডিজাইন করা হয়েছে যে উইজেটের অভ্যন্তরীণ অবস্থা পরিবর্তিত হয়েছে এবং UI পুনর্নির্মাণ প্রয়োজন। setState কল না করলে, Flutter পরিবর্তন সম্পর্কে জানে না — এমনকি State ফিল্ড পরিবর্তিত হলেও, প্যারেন্ট দ্বারা পরবর্তী বাধ্যতামূলক পুনর্নির্মাণ না হওয়া পর্যন্ত ইন্টারফেস অপরিবর্তিত থাকবে।
পদ্ধতি স্বাক্ষর: void setState(VoidCallback fn)। কলব্যাক setState-এর ভিতরে সিঙ্ক্রোনাসভাবে নির্বাহিত হয় এবং এর সমাপ্তির পরেই State নোংরা হিসেবে চিহ্নিত হয়। এটি নিশ্চিত করে যে পুনর্নির্মাণের আগে সমস্ত পরিবর্তন পারমাণবিকভাবে প্রয়োগ করা হয়। Dart ভাষা স্পেসিফিকেশন (Dart Team, 2026) অনুযায়ী, setState-এর পারমাণবিকতা রেস কন্ডিশন প্রতিরোধ করে যেখানে build আংশিকভাবে আপডেট হওয়া অবস্থা দেখতে পারে।
setState কোনো আর্গুমেন্ট নেয় না, কোনো মান ফেরত দেয় না এবং ওভাররাইড করা যায় না। এটি State ক্লাসের একটি ফাইনাল (সিল) পদ্ধতি। ডেভেলপার এর আচরণ পরিবর্তন করতে পারে না — শুধুমাত্র উদ্দেশ্য অনুযায়ী ব্যবহার করতে পারে। State-এর বাইরে (যেমন, অন্য ক্লাস থেকে) setState কল করার প্রচেষ্টা অসম্ভব কারণ পদ্ধতিটি State ক্লাসে ঘোষিত।
একটি সাধারণ ভুল ধারণা হলো মনে করা যে setState নিজেই অবস্থা পরিবর্তন করে। এটি সত্য নয়। setState শুধুমাত্র পাস করা কলব্যাক কল করে (যাতে ডেভেলপার ফিল্ড পরিবর্তন করে) এবং তারপর ফ্রেমওয়ার্ককে build-এর প্রয়োজনীয়তা জানায়। কলব্যাক বাধ্যতামূলক — null বা খালি কলব্যাক পাস করলে ত্রুটি হবে।
setState()-এর কার্যপ্রণালী চারটি ধাপে বিভক্ত করা যেতে পারে। প্রথম — কলব্যাক সহ পদ্ধতি কল করা। দ্বিতীয় — কলব্যাকের সিঙ্ক্রোনাস নির্বাহ, যার ভিতরে State ফিল্ড পরিবর্তিত হয়। তৃতীয় — State একটি বিশেষ ফিল্ড _dirty-তে নোংরা হিসেবে চিহ্নিত হয়। চতুর্থ — বর্তমান মাইক্রোটাস্কের শেষে, Flutter সমস্ত নোংরা উপাদানের মাধ্যমে পুনরাবৃত্তি করে এবং ট্রিতে উপস্থিতির ক্রমে তাদের build কল করে।
একটি গুরুত্বপূর্ণ বিবরণ: setState তাৎক্ষণিকভাবে build কল করে না। Flutter ব্যাচ আপডেট কৌশল ব্যবহার করে: সমস্ত নোংরা উপাদান সংগ্রহ করা হয় এবং একটি একক ফ্রেমে পুনর্নির্মিত হয়। এর অর্থ হলো, যদি setState একটি সিঙ্ক্রোনাস ব্লকের মধ্যে একাধিকবার কল করা হয়, build শুধুমাত্র একবার নির্বাহিত হবে — সমস্ত পরিবর্তন সম্পূর্ণ হওয়ার পরে। এই অপটিমাইজেশন প্রতি ফ্রেমে একাধিক পুনর্নির্মাণ প্রতিরোধ করে।
Flutter Engine Team (Google, 2025) অনুযায়ী, নোংরা ফ্ল্যাগ প্রক্রিয়া BuildOwner._dirtyElements পাসের উপর ভিত্তি করে। প্রতিটি নোংরা StatefulElement তালিকায় যুক্ত হয় এবং ফ্রেম আপডেট পর্যায়ে প্রক্রিয়াজাত হয়। যদি কোনো উইজেট প্রক্রিয়াকরণের আগে ট্রি থেকে সরানো হয়, তবে এটি স্বয়ংক্রিয়ভাবে নোংরা উপাদানের তালিকা থেকে বাদ দেওয়া হয়।
কাউন্টার বৃদ্ধি সহ setState()-এর মৌলিক উদাহরণ। সঠিক ব্যবহার দেখায়: কলব্যাকের ভিতরে ফিল্ড পরিবর্তন:
class _CounterState extends State<CounterWidget> {
int _count = 0;
void _increment() {
setState(() {
_count++; // কলব্যাকের ভিতরে ফিল্ড পরিবর্তন
});
}
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: _increment,
child: Text('$_count'),
);
}
}
টেক্সট ফিল্ড এবং কন্ট্রোলার সহ উদাহরণ — পাসওয়ার্ড দৃশ্যমানতা ব্যবস্থাপনার জন্য setState():
class _PasswordFieldState extends State<PasswordField> {
bool _obscured = true;
final _controller = TextEditingController();
void _toggleVisibility() {
setState(() {
_obscured = !_obscured;
});
}
@override
Widget build(BuildContext context) {
return TextField(
controller: _controller,
obscureText: _obscured,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(_obscured ? Icons.visibility : Icons.visibility_off),
onPressed: _toggleVisibility,
),
),
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}
এই উদাহরণে, setState() শুধুমাত্র বুলিয়ান ফিল্ড _obscured পরিবর্তন করে, যা নতুন আইকন এবং ডিসপ্লে মোড সহ TextField পুনর্নির্মাণ শুরু করে। টেক্সট কন্ট্রোলার পুনরায় তৈরি হয় না — এটি initState-তে একবার আরম্ভ করা হয় এবং dispose-তে মুক্ত করা হয়।
যদি আপনার একাধিক ফিল্ড পরিবর্তনের প্রয়োজন হয়, সমস্ত পরিবর্তন একটি setState-এর ভিতরে করা উচিত। এটি নিশ্চিত করে যে build একটি সামঞ্জস্যপূর্ণ অবস্থা দেখবে:
setState(() {
_isLoading = false;
_items = newItems;
_error = null;
});
একটি কলব্যাকে তিনটি ফিল্ড পরিবর্তন করা হয় — build একবার নির্বাহিত হবে এবং সমস্ত পরিবর্তন একসাথে দেখবে। যদি প্রতিটি কল আলাদা setState হতো, তবুও build নোংরা উপাদানের ব্যাচ প্রক্রিয়াকরণের কারণে শুধুমাত্র একবার নির্বাহিত হতো।
setState()-এর সবচেয়ে গুরুত্বপূর্ণ সূক্ষ্মতাগুলির মধ্যে একটি হলো অ্যাসিনক্রোনাস অপারেশনের সাথে এর আচরণ। setState কলব্যাক সিঙ্ক্রোনাসভাবে নির্বাহিত হয়, কিন্তু যদি এর ভিতরে await কল করা হয়, তাহলে await-এর পরে কোড setState সম্পূর্ণ হওয়ার পরে নির্বাহিত হবে। এর অর্থ হলো await-এর পরে ফিল্ড পরিবর্তন বর্তমান setState দ্বারা ক্যাপচার করা হবে না।
সঠিক পদ্ধতি: অ্যাসিনক্রোনাস অপারেশন setState-এর বাইরে করা হয়, এবং setState এটি সম্পূর্ণ হওয়ার পরে কল করা হয়। ফলাফল গ্রহণ এবং setState কল করার মধ্যে সমস্ত কোড await-এর পরে সিঙ্ক্রোনাস প্রসঙ্গে চলে:
// সঠিক: await setState-এর বাইরে
Future<void> _loadData() async {
final result = await ApiService.fetchData();
setState(() {
_data = result;
_isLoading = false;
});
}
// ভুল: await setState-এর ভিতরে — আপডেটের গ্যারান্টি নেই
void _loadDataWrong() {
setState(() async {
_data = await ApiService.fetchData(); // setState await সম্পূর্ণ হওয়ার আগে ফিরে আসে
_isLoading = false; // এই কোড setState দ্বারা ক্যাপচার করা হয়নি
});
}
Flutter ডক্স (Dart async patterns, 2026) অনুযায়ী, setState-এ অ্যাসিনক্রোনাস কলব্যাক পাস করা একটি অ্যান্টি-প্যাটার্ন কারণ setState একটি VoidCallback (সিঙ্ক্রোনাস ফাংশন) আশা করে, অথচ অ্যাসিনক্রোনাস ফাংশন একটি Future ফেরত দেয় যা উপেক্ষা করা হয়। এই ধরনের কলব্যাকে প্রথম await-এর পরে পরিবর্তনগুলি ফ্রেমওয়ার্ক দ্বারা সঠিকভাবে প্রক্রিয়াজাত হবে না।
অ্যাসিনক্রোনাস অপারেশনের পরে setState() কল করার আগে, সর্বদা mounted পরীক্ষা করুন:
if (mounted) {
setState(() => _data = data);
}
যদি অ্যাসিনক্রোনাস অপারেশনের সময় উইজেট ট্রি থেকে সরানো হয়, তবে mounted false হবে এবং setState কল করা হবে না। এটি ব্যতিক্রম এবং রিসোর্স লিক প্রতিরোধ করে।
setState() একটি সুবিধাজনক কিন্তু সম্ভাব্য ব্যয়বহুল প্রক্রিয়া যদি চিন্তাহীনভাবে ব্যবহার করা হয়। প্রতিটি setState কল পুরো উইজেট এবং তার সমস্ত বংশধর পুনর্নির্মাণ করে (যদি তারা const না হয়)। গভীর ট্রিতে বা ঘন ঘন কলের সাথে, এটি FPS হ্রাসের কারণ হতে পারে।
প্রধান অপটিমাইজেশন কৌশল: পুনর্নির্মাণ এলাকা হ্রাস করুন (পরিবর্তনযোগ্য UI অংশ আলাদা StatefulWidgets-এ নিষ্কাশন করুন), অপরিবর্তনীয় চাইল্ডের জন্য const ব্যবহার করুন এবং প্যারেন্ট উইজেটে setState কল করা এড়িয়ে চলুন যদি শুধুমাত্র একটি ছোট UX বিবরণ পরিবর্তিত হয়। যদি অবস্থা উচ্চ ফ্রিকোয়েন্সিতে আপডেট হয় (অ্যানিমেশন, ডেটা স্ট্রিম), AnimatedBuilder বা ValueListenableBuilder বিবেচনা করুন।
Flutter Performance Best Practices (Flutter.dev, ফেব্রুয়ারি 2026) অনুযায়ী, বাস্তব অ্যাপ্লিকেশন প্রোফাইলিং দেখায় যে 40% পর্যন্ত setState কল const চাইল্ড উইজেট বা রিয়েক্টিভ বিল্ডার (StreamBuilder, FutureBuilder) দিয়ে প্রতিস্থাপন করা যেতে পারে। এটি গড় ফ্রেম নির্মাণ সময় 15–25% হ্রাস করে।
| পরিস্থিতি | বিকল্প | সুবিধা |
|---|---|---|
| অ্যানিমেশন | AnimatedBuilder | শুধুমাত্র অ্যানিমেটেড উইজেট পুনর্নির্মাণ করে |
| ডেটা স্ট্রিম | StreamBuilder | প্রতিটি স্ট্রিম উপাদানে প্রতিক্রিয়া জানায় |
| ভবিষ্যত ফলাফল | FutureBuilder | লোডিং/ত্রুটি অবস্থা পরিচালনা করে |
| স্থানীয় মান | ValueListenableBuilder | একক মান পরিবর্তনে প্রতিক্রিয়া জানায় |
setState()-এর বহুমুখিতা সত্ত্বেও, বড় প্রকল্পে এটি প্রধানত স্থানীয় অবস্থার জন্য ব্যবহৃত হয়। বৈশ্বিক বা ভাগ করা অবস্থার জন্য, বিশেষায়িত সমাধান ব্যবহার করা হয়, যার প্রতিটি setState প্রতিস্থাপন বা মোড়ক তৈরি করে।
Provider setState-এর অ্যানালগ হিসাবে ChangeNotifier + notifyListeners ব্যবহার করে, কিন্তু একাধিক উইজেট সাবস্ক্রাইব করার ক্ষমতা সহ। Bloc Streams ব্যবহার করে — StreamController-এ ইভেন্ট যোগ করে অবস্থা পরিবর্তন করা হয়। Riverpod পদ্ধতিগুলিকে একত্রিত করে, StatefulWidget-এর সাথে বাঁধন ছাড়াই স্থানীয় (StateProvider) এবং অ্যাসিনক্রোনাস (AsyncNotifier) উভয় ব্যবস্থাপনা প্রদান করে। তিনটি পদ্ধতিই ম্যানুয়ালি setState কল করার প্রয়োজনীয়তা দূর করে — ডেটা পরিবর্তন হলে UI আপডেট স্বয়ংক্রিয়ভাবে ঘটে।
Flutter Community Survey 2025 (Flutter Foundation, ডিসেম্বর 2025) অনুযায়ী, 74% ডেভেলপার setState ছাড়াও কমপক্ষে একটি স্টেট ম্যানেজমেন্ট টুল ব্যবহার করে। একই সময়ে, 92% টেক্সট ফিল্ড, চেকবক্স বা সাধারণ কাউন্টারের স্থানীয় ডেটার জন্য setState ব্যবহার চালিয়ে যায় — এটি সর্বোত্তম অনুশীলন হিসাবে বিবেচিত হয়।
প্রথম এবং সবচেয়ে বিপজ্জনক ভুল হলো dispose-এর পরে setState কল করা। initState-তে শুরু হওয়া অ্যাসিনক্রোনাস অপারেশন, ব্যবহারকারী স্ক্রীন ছেড়ে চলে গেছে, উইজেট সরানো হয়েছে, এবং অ্যাসিনক্রোনাস কলব্যাক setState কল করে — অ্যাপ ব্যতিক্রমের সাথে ক্র্যাশ করে। সমাধান — কল করার আগে সর্বদা mounted পরীক্ষা করুন।
দ্বিতীয় ভুল হলো build-এর ভিতরে setState কল করা। এটি একটি অসীম লুপের দিকে নিয়ে যায়: build → setState → নোংরা → build → setState → ... Flutter এই ধরনের কল ব্লক করে না (আপনি StackOverflowError পাবেন)। setState শুধুমাত্র একটি ইভেন্টের প্রতিক্রিয়ায় কল করা যেতে পারে (বাটন প্রেস, Future সম্পূর্ণ হওয়া, স্ট্রিম থেকে ডেটা)।
তৃতীয় ভুল হলো setState কল না করে State ফিল্ড পরিবর্তন করা। ডেভেলপার _count++ লেখে এবং UI আপডেট হওয়ার আশা করে। Flutter স্বয়ংক্রিয়ভাবে ফিল্ড পরিবর্তন ট্র্যাক করতে পারে না — এটির setState-এর মাধ্যমে স্পষ্ট সংকেত প্রয়োজন। এটি Vue.js-এর মতো রিয়েক্টিভ ফ্রেমওয়ার্ক থেকে মৌলিক পার্থক্য, যেখানে ডেটা পরিবর্তন স্বয়ংক্রিয়ভাবে আপডেট ট্রিগার করে।
চতুর্থ ভুল হলো অ্যাসিনক্রোনাস কলব্যাক (async lambda) সহ setState কল করা। অ্যাসিনক্রোনিসিটি বিভাগে বর্ণিত হিসাবে, await-এর পরে পরিবর্তনগুলি ক্যাপচার করা হবে না, যা পুনরুত্পাদন করা কঠিন বাগের দিকে নিয়ে যায়। একটি সিঙ্ক্রোনাস কলব্যাক ব্যবহার করুন এবং await-এর পরে setState কল করুন।
mounted পরীক্ষা করুনসচরাচর জিজ্ঞাসা
setState() Flutter-কে জানায় যে StatefulWidget-এর অভ্যন্তরীণ ডেটা পরিবর্তিত হয়েছে এবং UI পুনর্নির্মাণ প্রয়োজন। পদ্ধতিটি একটি কলব্যাক গ্রহণ করে, এটি সিঙ্ক্রোনাসভাবে নির্বাহ করে, উইজেটকে নোংরা চিহ্নিত করে এবং পরবর্তী ফ্রেমে build কল নির্ধারণ করে।
UI আপডেট হবে না। Flutter স্বয়ংক্রিয়ভাবে ফিল্ড পরিবর্তন ট্র্যাক করে না। ফিল্ডের মান মেমরিতে পরিবর্তিত হয়, কিন্তু উইজেট প্যারেন্ট দ্বারা পরবর্তী বাধ্যতামূলক পুনর্নির্মাণ পর্যন্ত পূর্বের অবস্থায় থাকে।
না। এটি একটি অসীম লুপের দিকে নিয়ে যায়: build setState কল করে, যা উইজেটকে নোংরা চিহ্নিত করে এবং আবার build কল করে। Flutter এই পরিস্থিতি ব্লক করে না — অ্যাপ StackOverflowError দিয়ে ক্র্যাশ করবে।
Build একবার নির্বাহিত হবে। Flutter সমস্ত নোংরা উপাদান সংগ্রহ করে এবং ফ্রেমের শেষে সেগুলি ব্যাচে পুনর্নির্মাণ করে। প্রক্রিয়াকরণের আগে দ্বিতীয় setState কেবল একই নোংরা উপাদান তালিকায় উপাদান যোগ করে — কোনও পুনরাবৃত্ত পুনর্নির্মাণ হয় না।
mounted একটি বুলিয়ান ফ্ল্যাগ যা নির্দেশ করে যে উইজেটটি এখনও ট্রিতে রয়েছে। যদি mounted পরীক্ষা না করে অ্যাসিনক্রোনাস অপারেশনের পরে setState কল করা হয় এবং উইজেটটি ইতিমধ্যে সরানো হয়ে থাকে — অ্যাপ "setState called after dispose" ব্যতিক্রমের সাথে ক্র্যাশ করে।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন