State: এটি কী, অবস্থা ব্যবস্থাপনা এবং কাজের নীতি

লেখক: IT Sectr প্রকাশিত: 2026-07-01 পড়ার সময়: 9 মিনিট

State হলো Flutter-এর কেন্দ্রীয় ডেটা ব্যবস্থাপনা অবজেক্ট, যা StatefulWidget-এর সাথে যুক্ত এবং পরিবর্তনযোগ্য তথ্য সংরক্ষণ ও ইন্টারফেস তৈরির জন্য দায়ী। অফিসিয়াল Flutter ডকুমেন্টেশন (Flutter.dev, 2026) অনুযায়ী, State উইজেটের পুরো জীবনচক্র জুড়ে বিদ্যমান থাকে এবং এর পুনর্নির্মাণ থেকে বেঁচে যায়, UI আপডেটের মধ্যে ডেটা সামঞ্জস্য নিশ্চিত করে। উইজেটের নিজের বিপরীতে, State তার ফিল্ডগুলি পরিবর্তন করতে পারে এবং setState কলের মাধ্যমে পুনর্নির্মাণ শুরু করতে পারে।

মূল বিষয়

  • State — একটি অবজেক্ট যা StatefulWidget-এর পরিবর্তনযোগ্য ডেটা সংরক্ষণ করে এবং setState-এর মাধ্যমে এর পুনর্নির্মাণ পরিচালনা করে
  • জীবনচক্র — State initState, didChangeDependencies, build, didUpdateWidget এবং dispose-এর মধ্য দিয়ে যায়, প্রতিটি ধাপের স্পষ্ট উদ্দেশ্য রয়েছে
  • mounted — একটি ফ্ল্যাগ যা নির্দেশ করে যে State এখনও উইজেট ট্রিতে আছে এবং নিরাপদে setState কল করতে পারে
  • widget — সংযুক্ত StatefulWidget-এর একটি রেফারেন্স, যা প্যারেন্ট প্যারামিটার পড়ার জন্য State প্রপার্টির মাধ্যমে অ্যাক্সেসযোগ্য
  • বিচ্ছিন্নতা — State অন্যান্য State থেকে বিচ্ছিন্ন; ডেটা বিনিময়ের জন্য InheritedWidget বা বাহ্যিক অবস্থা ব্যবস্থাপনা টুল ব্যবহার করা হয়

Flutter-এ State কী?

State হলো Flutter আর্কিটেকচারের একটি অবজেক্ট যা StatefulWidget-এর পরিবর্তনযোগ্য ডেটা সংরক্ষণ করে এবং নির্ধারণ করে কিভাবে এই ডেটা ইন্টারফেসে প্রদর্শিত হয়। প্রতিটি StatefulWidget, ট্রিতে স্থাপিত হলে, createState মেথডের মাধ্যমে ঠিক একটি State অবজেক্ট তৈরি করে। State উইজেট থেকে স্বাধীনভাবে বিদ্যমান থাকে: যদি প্যারেন্ট নতুন প্যারামিটার সহ StatefulWidget পুনর্নির্মাণ করে, State একই থাকে এবং widget প্রপার্টির মাধ্যমে আপডেটেড উইজেট গ্রহণ করে।

Flutter আর্কিটেকচারাল ওভারভিউ (Google, 2026) অনুযায়ী, Widget এবং State-এর পৃথকীকরণ একটি সচেতন আর্কিটেকচারাল সিদ্ধান্ত যা ফ্রেমওয়ার্ককে ট্রি এলিমেন্ট পুনরায় ব্যবহার করতে দেয়। উইজেট (একটি হালকা বর্ণনা) একাধিকবার তৈরি এবং ধ্বংস করা যেতে পারে, কিন্তু State (ডেটাসহ একটি ভারী অবজেক্ট) মেমরিতে থাকে যতক্ষণ এলিমেন্ট ট্রিতে থাকে। এটি প্যারেন্ট উইজেটের ঘন ঘন পুনর্নির্মাণের সময় ডেটা ক্ষতি রোধ করে।

State জেনেরিকের মাধ্যমে StatefulWidget ইন্টারফেস বাস্তবায়ন করে: class _MyState extends State<MyWidget>। জেনেরিক State-কে একটি নির্দিষ্ট StatefulWidget প্রকারের সাথে বাঁধে, যা widget প্রপার্টির মাধ্যমে তার ফিল্ডগুলিতে টাইপ-নিরাপদ অ্যাক্সেস প্রদান করে।

State কোথায় সংরক্ষিত হয়?

State অবজেক্ট StatefulElement-এ সংরক্ষিত হয় — Widget এবং RenderObject-এর মধ্যে একটি মধ্যবর্তী স্তর। StatefulElement createState-এর মাধ্যমে State তৈরি করে, এটির একটি রেফারেন্স রাখে এবং State-কে মালিক হিসাবে পাস করে। Element কেবল তখনই ধ্বংস হয় যখন উইজেট ট্রি থেকে সরানো হয় — ততক্ষণ পর্যন্ত, State মেমরিতে থাকে।

State-এর জীবনচক্র

State-এর জীবনচক্র নির্ধারিত এবং কঠোর ক্রমে কলের সমন্বয়ে গঠিত। এই ক্রম বোঝা সঠিক সম্পদ ব্যবস্থাপনা এবং মেমরি লিক প্রতিরোধের ভিত্তি।

initState — আরম্ভ

initState State তৈরি হলে প্রথমে কল করা হয়। এই মেথডে, কন্ট্রোলার, স্ট্রিম সাবস্ক্রিপশন, টাইমার এবং ফিল্ডের প্রাথমিক মান আরম্ভ করা হয়। প্রথম লাইনে super.initState() কল করা বাধ্যতামূলক। initState ধাপে, উইজেট ট্রি এখনও সম্পূর্ণরূপে মাউন্ট হয়নি, তাই MediaQuery.of(context)-এর মতো মেথড সঠিকভাবে কাজ নাও করতে পারে।

didChangeDependencies

didChangeDependencies initState-এর পরে এবং InheritedWidget নির্ভরতা পরিবর্তিত হলে কল করা হয়। এখানে, initState-এ নয়, MediaQuery.of(context) বা Theme.of(context) কল করা উচিত, কারণ ততক্ষণে ট্রি ইতিমধ্যে মাউন্ট হয়েছে। এই মেথডটি কল করা হয় যদি উইজেট ভিন্ন প্রসঙ্গে চলে যায় যেখানে InheritedWidget অন্যান্য মান প্রদান করে।

build — UI নির্মাণ

build হলো State-এর প্রধান মেথড যা উইজেট ট্রি ফেরত দেয়। এটি initState-এর পরে, didChangeDependencies-এর পরে এবং প্রতিটি setState-এর পরে কল করা হয়। build মেথডের কোনও পার্শ্ব প্রতিক্রিয়া থাকা উচিত নয় — এটি কেবল State ফিল্ডের বর্তমান মানের উপর ভিত্তি করে ইন্টারফেস বর্ণনা করে।

didUpdateWidget

didUpdateWidget কল করা হয় যখন প্যারেন্ট নতুন প্যারামিটার সহ StatefulWidget পুনর্নির্মাণ করে। State পুরানো উইজেটে oldWidget-এর মাধ্যমে অ্যাক্সেস পায় এবং এটি নতুনটির সাথে তুলনা করতে পারে। যদি প্যারামিটার পরিবর্তিত হয়, তাহলে অবস্থা আপডেট করা, নতুন ডেটা লোড করা বা অ্যানিমেশন পুনরায় শুরু করা যেতে পারে।

dispose — সম্পদ মুক্ত করা

dispose চূড়ান্ত মেথড যেখানে সমস্ত সম্পদ মুক্ত করা হয়: কন্ট্রোলার, সাবস্ক্রিপশন, টাইমার। dispose-এর পরে, State-কে মৃত হিসাবে চিহ্নিত করা হয়: mounted false ফেরত দেয়, setState কল করলে ব্যতিক্রম উৎপন্ন হয়। মেথডের শেষ লাইনে super.dispose() কল করা বাধ্যতামূলক।

মেথডকখন কল করা হয়বাধ্যতামূলক super
initStateState তৈরি হলেহ্যাঁ, প্রথম লাইনে
didChangeDependenciesinitState-এর পরে এবং InheritedWidget পরিবর্তিত হলেহ্যাঁ
buildinitState, didChangeDependencies, setState-এর পরেনা
didUpdateWidgetপ্যারেন্ট থেকে নতুন উইজেট এলেহ্যাঁ
setStateডেভেলপার কল করলেনা
disposeট্রি থেকে সরানো হলেহ্যাঁ, শেষ লাইনে

State কীভাবে কাজ করে?

State-এর কার্যপ্রণালী তিনটি মূল নীতির উপর ভিত্তি করে: Element-এর সাথে সংযোগ, setState-এর মাধ্যমে প্রতিক্রিয়াশীলতা এবং widget প্রপার্টির মাধ্যমে প্যারেন্ট অ্যাক্সেস। যখন Flutter এলিমেন্ট ট্রি তৈরি করে এবং StatefulElement-এর সম্মুখীন হয়, তখন এটি সংযুক্ত উইজেটের createState কল করে। তৈরি State এলিমেন্টে সংরক্ষিত হয় এবং যতক্ষণ এলিমেন্ট সরানো না হয় ততক্ষণ বিদ্যমান থাকে।

যখন setState কল করা হয়, State নিজেকে নোংরা হিসাবে চিহ্নিত করে এবং পরবর্তী ফ্রেমের জন্য পুনর্নির্মাণ নির্ধারণ করে। গুরুত্বপূর্ণ: setState অবিলম্বে build কল করে না — এটি কেবল পুনর্নির্মাণের প্রয়োজনীয়তা নিবন্ধন করে। Flutter বর্তমান ফ্রেমের সমস্ত নোংরা এলিমেন্ট সংগ্রহ করে এবং সেগুলিকে ব্যাচে পুনর্নির্মাণ করে, যা কর্মক্ষমতা অপ্টিমাইজ করে। build কল করার পরে, State পরিষ্কার অবস্থায় ফিরে আসে।

widget প্রপার্টি State-কে StatefulWidget কনস্ট্রাক্টরে পাস করা প্যারামিটার পড়তে দেয়। যেহেতু StatefulWidget অপরিবর্তনীয় (StatelessWidget-এর মতো), এর ফিল্ডগুলি পরিবর্তিত হয় না — যখন প্যারামিটার পরিবর্তিত হয়, প্যারেন্ট একটি নতুন উইজেট তৈরি করে, এবং State এটি didUpdateWidget-এর মাধ্যমে গ্রহণ করে। এটি নিশ্চিত করে যে State সর্বদা বর্তমান প্যারেন্ট ডেটার সাথে কাজ করে।

Dart কোড উদাহরণ

টাইমার দ্বারা পরিবর্তিত ফিল্ড সহ State-এর মৌলিক উদাহরণ। initState, setState এবং dispose প্রদর্শন করে:

dart
class _TimerWidgetState extends State<TimerWidget> {
  int _seconds = 0;
  Timer? _timer;

  @override
  void initState() {
    super.initState();
    _timer = Timer.periodic(
      const Duration(seconds: 1),
      (_) => setState(() => _seconds++),
    );
  }

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Text('$_seconds seconds elapsed');
  }
}

প্যারেন্ট প্যারামিটার অ্যাক্সেস করতে এবং didUpdateWidget-এর মাধ্যমে তাদের পরিবর্তনে প্রতিক্রিয়া জানাতে widget প্রপার্টি ব্যবহারের উদাহরণ:

dart
class _GreetingState extends State<GreetingWidget> {
  String _displayName = '';

  @override
  void initState() {
    super.initState();
    _displayName = _formatName(widget.name);
  }

  @override
  void didUpdateWidget(GreetingWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.name != oldWidget.name) {
      setState(() {
        _displayName = _formatName(widget.name);
      });
    }
  }

  String _formatName(String name) => name.trim().isEmpty ? 'Guest' : name;

  @override
  Widget build(BuildContext context) {
    return Text('Hello, $_displayName!');
  }
}

দ্বিতীয় উদাহরণে, State ইনপুট প্যারামিটার name-এর পরিবর্তন ট্র্যাক করে এবং শুধুমাত্র প্রকৃত পরিবর্তন হলে প্রদর্শন পুনরায় বিন্যাস করে। widget.name != oldWidget.name চেক ছাড়া, মেথডটি প্রতিটি প্যারেন্ট পুনর্নির্মাণে কল হতো, এমনকি নাম পরিবর্তন না হলেও — ফ্রেমওয়ার্কের জন্য অপ্রয়োজনীয় কাজ।

State বনাম StatefulWidget

State এবং StatefulWidget Flutter আর্কিটেকচারের দুটি ভিন্ন ক্লাস যা ভিন্ন ভূমিকা পালন করে। StatefulWidget একটি হালকা অপরিবর্তনীয় আবরণ যা উইজেট কনফিগারেশন বর্ণনা করে এবং State তৈরি করে। State একটি ভারী অবজেক্ট যা পরিবর্তনযোগ্য ডেটা সংরক্ষণ করে, সাবস্ক্রিপশন পরিচালনা করে এবং UI তৈরি করে। এই পৃথকীকরণ Flutter-কে অবস্থা না হারিয়ে উইজেট তৈরি এবং ধ্বংস করতে দেয়।

StatefulWidget-এর সমস্ত ফিল্ড final হতে হবে এবং কনস্ট্রাক্টরে সেট করতে হবে — এগুলি তৈরির পরে পরিবর্তিত হয় না। State, অন্যদিকে, যেকোনো সময় তার ফিল্ড পরিবর্তন করতে পারে, কিন্তু সমস্ত পরিবর্তনের আগে setState কল করতে হবে যাতে Flutter পুনর্নির্মাণের প্রয়োজনীয়তা সম্পর্কে জানতে পারে। এটি মূল পার্থক্য: StatefulWidget হলো “কী দেখাতে হবে”, State হলো “কীভাবে দেখাতে হবে এবং কী ডেটা ব্যবহার করতে হবে”।

Flutter সোর্স কোড বিশ্লেষণ (Flutter SDK, 2026) অনুযায়ী, StatefulWidget-এ কেবল একটি বাধ্যতামূলক ফিল্ড রয়েছে — createState, যেখানে State-এর BuildContext-এ অ্যাক্সেস আছে, স্ট্রিমে সাবস্ক্রাইব করতে পারে, অ্যানিমেশন এবং কন্ট্রোলার পরিচালনা করতে পারে। StatefulWidget-কে যতটা সম্ভব সরল রাখার, সমস্ত যুক্তি State-তে স্থানান্তর করার পরামর্শ দেওয়া হয়।

কেন StatefulWidget State হতে পারে না?

Widget এবং State-এর পৃথকীকরণ একটি আর্কিটেকচারাল সিদ্ধান্ত যা কনফিগারেশনের অপরিবর্তনীয়তা নিশ্চিত করে। যদি StatefulWidget নিজেই অবস্থা সংরক্ষণ করত, তাহলে প্রতিটি প্যারেন্ট পুনর্নির্মাণে অবস্থা হারিয়ে যেত। অবস্থাকে একটি পৃথক অবজেক্টে সরিয়ে, Flutter নিশ্চিত করে যে ডেটা পুনর্নির্মাণ থেকে বেঁচে যায়, যখন উইজেট হালকা এবং তুলনাযোগ্য থাকে।

উইজেটগুলির মধ্যে অবস্থা ব্যবস্থাপনা

State অবজেক্ট বিচ্ছিন্ন — অন্যান্য উইজেটের State-তে এর সরাসরি অ্যাক্সেস নেই। উইজেটগুলির মধ্যে ডেটা বিনিময়ের জন্য InheritedWidget বা বাহ্যিক অবস্থা ব্যবস্থাপনা টুল ব্যবহার করা হয়: Provider, Riverpod, Bloc, Redux। প্রতিটি পদ্ধতি সমস্যাটি ভিন্নভাবে সমাধান করে: InheritedWidget উইজেট ট্রির মাধ্যমে কাজ করে, Provider DI কন্টেইনারের মাধ্যমে, Bloc ইভেন্ট স্ট্রিমের মাধ্যমে।

টুলের পছন্দ প্রকল্পের স্কেলের উপর নির্ভর করে। ছোট অ্যাপ্লিকেশনের জন্য, InheritedWidget এবং স্থানীয় State যথেষ্ট। মাঝারি এবং বড় প্রকল্পের জন্য, Riverpod বা Bloc সুপারিশ করা হয় — তারা পরীক্ষণযোগ্যতা, পূর্বাভাসযোগ্যতা এবং UI থেকে যুক্তির পৃথকীকরণ নিশ্চিত করে। State তখন কেবল স্থানীয় উইজেট ডেটার (ফোকাস, স্ক্রোল, অ্যানিমেশন) জন্য ব্যবহৃত হয়।

Flutter কমিউনিটি সার্ভে 2025 (Flutter Foundation, ডিসেম্বর 2025) অনুযায়ী, Riverpod নতুন প্রকল্পে সবচেয়ে জনপ্রিয় অবস্থা ব্যবস্থাপনা সমাধান (38%), তারপরে Bloc (31%) এবং Provider (22%)। তিনটি টুলই State-এর সাথে সামঞ্জস্যপূর্ণ এবং মানক জীবনচক্র ত্যাগ করার প্রয়োজন নেই।

স্থানীয় বনাম বৈশ্বিক অবস্থা

  • স্থানীয় অবস্থা — নির্দিষ্ট উইজেটের State-এ (স্ক্রোল অবস্থান, ফোকাস অবস্থা)
  • বৈশ্বিক অবস্থা — বাহ্যিক সঞ্চয়স্থানে (ব্যবহারকারীর ডেটা, সেটিংস, ক্যাশ)
  • নিয়ম: যদি ডেটা কেবল একটি উইজেট দ্বারা ব্যবহৃত হয় — State-এ সংরক্ষণ করুন
  • যদি ডেটা 2+ উইজেট দ্বারা ব্যবহৃত হয় — Riverpod/Bloc/Provider-এ সরান

সাধারণ ভুল

প্রথম ভুল হলো অ্যাসিঙ্ক্রোনাস কলব্যাকে setState-এর আগে mounted চেক করতে ভুলে যাওয়া। যখন উইজেট ট্রি থেকে সরানো হয় (উদাহরণস্বরূপ, ব্যবহারকারী স্ক্রিন ছেড়ে চলে গেছে), কিন্তু একটি অ্যাসিঙ্ক্রোনাস অপারেশন (HTTP অনুরোধ) এখনও চলছে, এটি সম্পূর্ণ হওয়ার পরে State ইতিমধ্যে মৃত। মৃত State-এ setState কল করলে ব্যতিক্রম উৎপন্ন হয়। চেক if (mounted) setState(...) সমস্যা সমাধান করে।

দ্বিতীয় ভুল হলো didChangeDependencies-এর পরিবর্তে initState-এ InheritedWidget নির্ভরতা আরম্ভ করা। initState-এ, প্রসঙ্গ এখনও মাউন্ট হয়নি, তাই MediaQuery.of(context) ব্যতিক্রম উৎপন্ন করবে। সমস্ত InheritedWidget নির্ভরতা didChangeDependencies বা build-এ সেট করা উচিত।

তৃতীয় ভুল হলো setState কল না করে ফিল্ড পরিবর্তন করা। যদি ডেভেলপার setState ছাড়া State ফিল্ড পরিবর্তন করে, Flutter পরিবর্তন সম্পর্কে জানতে পারবে না এবং UI আপডেট হবে না। উদাহরণস্বরূপ: পরবর্তী setState((){}) ছাড়া _list.add(item) তালিকা পরিবর্তন করবে, কিন্তু স্ক্রিন একই থাকবে।

setState-এর আগে mounted চেক

State-এ অ্যাসিঙ্ক্রোনাস অপারেশনের জন্য নিরাপত্তা প্যাটার্ন:

dart
Future<void> _fetchData() async {
  final data = await ApiService.fetch();
  if (mounted) {
    setState(() => _data = data);
  }
}

mounted চেক নিশ্চিত করে যে setState কেবল জীবিত State-এ কল করা হয়, যা “setState called after dispose” ব্যতিক্রম প্রতিরোধ করে।

প্রায়শই জিজ্ঞাসিত প্রশ্ন

State কীভাবে StatefulWidget থেকে আলাদা?

StatefulWidget একটি অপরিবর্তনীয় উইজেট কনফিগারেশন, যেখানে State একটি পরিবর্তনযোগ্য অবজেক্ট যা ডেটা সংরক্ষণ করে এবং জীবনচক্র পরিচালনা করে। উইজেট পুনরায় তৈরি করা যেতে পারে, State পারে না। StatefulWidget createState-এর মাধ্যমে State তৈরি করে।

একটি StatefulWidget-এর জন্য কয়টি State অবজেক্ট তৈরি হয়?

ঠিক একটি। createState মেথড একবার কল করা হয় যখন StatefulWidget প্রথমবার ট্রিতে স্থাপিত হয়। এমনকি যদি প্যারেন্ট একাধিকবার পুনর্নির্মাণ করে, State অবজেক্ট একই থাকে যতক্ষণ না উইজেটের প্রকার বা Key পরিবর্তিত হয়।

State-এ mounted কী?

mounted একটি বুলিয়ান ফ্ল্যাগ যা দেখায় যে State উইজেট ট্রিতে আছে কিনা। dispose কল করার পরে, mounted false হয়। ব্যতিক্রম এড়াতে অ্যাসিঙ্ক্রোনাস কলব্যাকে setState-এর আগে চেক করার জন্য ব্যবহৃত হয়।

State কি StatefulWidget ছাড়া ব্যবহার করা যেতে পারে?

না। State সর্বদা জেনেরিকের মাধ্যমে একটি নির্দিষ্ট StatefulWidget-এর সাথে আবদ্ধ: State<T extends StatefulWidget>। উইজেটের সাথে সংযোগ ছাড়া সরাসরি State তৈরি করা আর্কিটেকচারালি অসম্ভব।

dispose-এ setState কল করলে কী হয়?

একটি ব্যতিক্রম উৎপন্ন হয়: “setState called after dispose”। dispose-এর পরে, State মৃত বিবেচিত হয়, এবং setState-এর মাধ্যমে UI পুনর্নির্মাণের যে কোনও প্রচেষ্টা নিষিদ্ধ। সমাধান হলো প্রতিটি setState-এর আগে mounted চেক করা।

সারাংশ

  • State — StatefulWidget ডেটা ব্যবস্থাপনা অবজেক্ট যা পরিবর্তনযোগ্য ফিল্ড সংরক্ষণ করে এবং setState-এর মাধ্যমে UI পুনর্নির্মাণ শুরু করে
  • জীবনচক্র বাধ্যতামূলক মেথড initState, didChangeDependencies, build, didUpdateWidget এবং dispose অন্তর্ভুক্ত করে, প্রতিটির নিজস্ব উদ্দেশ্য রয়েছে
  • mounted — একটি গুরুত্বপূর্ণ নিরাপত্তা ফ্ল্যাগ যা উইজেট ট্রি থেকে সরানোর পরে setState কল প্রতিরোধ করে
  • widget — সংযুক্ত StatefulWidget প্যারামিটার অ্যাক্সেসের জন্য State প্রপার্টি, didUpdateWidget-এর মাধ্যমে আপডেট করা হয়
  • বিচ্ছিন্নতা — State-এর অন্যান্য State-এ অ্যাক্সেস নেই; আন্তঃ-উইজেট যোগাযোগ InheritedWidget বা বাহ্যিক টুলের মাধ্যমে বাস্তবায়িত হয়
  • setState — অবিলম্বে build কল করে না, বরং পরবর্তী ফ্রেমে পুনর্নির্মাণের জন্য State-কে নোংরা চিহ্নিত করে
  • নিয়ম — স্থানীয় উইজেট ডেটার জন্য State ব্যবহার করুন; বৈশ্বিক অবস্থা বাহ্যিক স্তরে (Riverpod, Bloc) সরান

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন