স্কিপ করে মূল কন্টেন্ট এ যাও

প্রভাইডার রিড করা

এই গাইডটি পড়ার আগে, খেয়াল রাখবেন যেন প্রথমে যেন আপনি প্রভাইডার এর ব্যাপারে পড়েন

আমরা এই গাইড এ দেখব কিভাবে একটি প্রভাইডার কনসিউম করতে পারব

একটি "ref" অবজেক্ট ধারণ করা

প্রথমে এবং শুরুতে কোন প্রভাইডার পড়ার আগে আমাদের "ref" অবজেক্টটি ধারণ করতে হবে।

এই অবজেক্টটি আমাদের অনুমতি দেই প্রভাইডারদের সাথে আদানপ্রদান করার, সেটি উইজেট ও করতে পারেন অথবা অন্য প্রভাইডার থেকে ও পারবেন।

প্রভাইডার হতে একটি "ref" অবজেক্ট ধারণ করা

সকল প্রভাইডার "ref" প্যারামিটার হিসেবে পাইঃ

final provider = Provider((ref) {
// ref দিয়ে অন্য প্রভাইডার ধারণ করুন
final repository = ref.watch(repositoryProvider);

return SomeValue(repository);
})

এই প্যারামিটার প্রভাইডার দ্বারা উন্মুক্ত ভ্যালু পাস করা নিরাপদ.

উদাহারণসরূপ, একটি কমন সিনারিও হচ্ছে, "ref" অবজেক্টটি StateNotifier এ পাস করাঃ


final counterProvider = StateNotifierProvider<Counter, int>((ref) {
return Counter(ref);
});

class Counter extends StateNotifier<int> {
Counter(this.ref) : super(0);

final Ref ref;

void increment() {
// Counter এই "ref" অবজেক্ট ব্যবহার করে অন্য প্রভাইডার পড়তে পারবে
final repository = ref.read(repositoryProvider);
repository.post('...');
}
}

এরকম করার পরে আমদের Counter ক্লাস অন্য প্রভাইডার পরার অনুমতি পায়।

উইজেট হতে একটি "ref" অবজেক্ট ধারণ করা

উইজেটে প্রাকৃতিক ভাবে কোন "ref" অবজেক্ট থাকে না. কিন্তু Riverpod একাধিক সমাধান অফার করে এই অবজেক্টটি ধারণ করার জন্যে।

ConsumerWidget এ এক্সটেন্ড করা StatelessWidget এর পরিবর্তে

সবচেয়ে কমন সমাধান হচ্ছে আমাদের StatelessWidget কে ConsumerWidget দিয়ে পরিবর্তন করা, যখন আমরা একটি উইজেট তৈরি করি।

ConsumerWidget অনেকাংশে StatelessWidget, শুধুমাত্র কিছু পরিবর্তন যেমন এর বিল্ড মেথড একটি এক্সট্রা প্যারমিটার পায় যা হচ্ছেঃ "ref" অবজেক্ট

একটি সাধারণ ConsumerWidget দেখতে এরকম হবেঃ


class HomeView extends ConsumerWidget {
const HomeView({super.key});


Widget build(BuildContext context, WidgetRef ref) {
// use ref to listen to a provider
final counter = ref.watch(counterProvider);
return Text('$counter');
}
}

ConsumerStatefulWidget+ConsumerState এ এক্সটেন্ড করা StatefulWidget+State এর পরিবর্তে

ConsumerWidget এর মতই, ConsumerStatefulWidget এবং ConsumerState এর সমতুল্য হচ্ছে StatefulWidget এবং এর State, আর তফাৎ হচ্ছে এটিতে "ref" অবজেক্ট রয়েছে

এবার, "ref" বিল্ড মেথড এ একটি প্যারামিটার হিসেবে পাস করা হয় না, বরং এটি ConsumerState অবজেক্ট এর একটি প্রপার্টিঃ


class HomeView extends ConsumerStatefulWidget {
const HomeView({super.key});


HomeViewState createState() => HomeViewState();
}

class HomeViewState extends ConsumerState<HomeView> {

void initState() {
super.initState();
// "ref" একটি StatefulWidget এর সকল লাইফসাইকেল এ ব্যবহার করে যাবে.
ref.read(counterProvider);
}


Widget build(BuildContext context) {
// আমরা আর ব্যবহার করতে পারব "ref" কে বিল্ড মেথড এ একটি প্রভাইডার রিড/লিসেন করার ক্ষেত্রে
final counter = ref.watch(counterProvider);
return Text('$counter');
}
}

HookConsumerWidget এক্সটেন্ড করা HookWidget এর পরিবর্তে

এই সলিউশন টা flutter_hooks ব্যবহারকারীদের জন্যে. কারণ flutter_hooks চায় HookWidget এক্সটেন্ড করা এটি কাজ করার জন্য, যে উইজেট গুলা hooks ব্যবহার করে সেগুলা ConsumerWidget এক্সটেন্ড করতে পারে না.

একটি সমাধান, যেটি hooks_riverpod প্যাকেজ দ্বারা সম্ভব হয়েছে, তা হচ্ছে HookWidget কে HookConsumerWidget রিপ্লেস করা. HookConsumerWidget একি সাথে ConsumerWidget এবং HookWidget এর কাজ একসাথে করে.এটি আমাদের অনুমতি দেই একইসাথে প্রভাইডার লিসেন/রিড করার এবং hooks ব্যবহার করার।

একটি উদাহারণ হবে:


class HomeView extends HookConsumerWidget {
const HomeView({super.key});


Widget build(BuildContext context, WidgetRef ref) {
// HookConsumerWidget অনুমতি দেয় বিল্ড মেথড এর ভিতরে hooks ব্যবহার করার
final state = useState(0);

// আমরা একইসাথে "ref" দিয়ে প্রভাইডার রিড করতে পারব
final counter = ref.watch(counterProvider);
return Text('$counter');
}
}

Consumer and HookConsumer widgets

একটি ফাইনাল সমাধান হবে "ref" অবজেক্টকে উইজেট এর মধ্যে ধারণ করার তা হল Consumer/HookConsumer এর উপর নির্ভর করা.

এই ক্লাসগুলি হল উইজেট যা একই সাথে "ref" পেতে ব্যবহার করা যেতে পারে যা ConsumerWidget/HookConsumerWidget এর একই বৈশিষ্ট্য।

এই উইজেটগুলো একটি রাস্তা হতে পারে একটি "ref" অবজেক্ট পাওয়ার কোন ক্লাস ডিফাইন করা ছাড়া। উদাহরণসরূপঃ

Scaffold(
body: HookConsumer(
builder: (context, ref, child) {
// HookConsumerWidget এর মতই, আমরা বিল্ডার এর ভিতরে হুকস ব্যবহার করতে পারি
final state = useState(0);

// আমরা একইসাথে "ref" দিয়ে প্রভাইডার রিড করতে পারব
final counter = ref.watch(counterProvider);
return Text('$counter');
},
),
);

Ref দিয়ে প্রভাইডার এর সাথে আদানপ্রদান

এখন আমরা যখন "ref" পেয়ে গেছি, আমরা এটা ব্যবহার শুরু করতে পারি।

"ref" এর তিনটি ব্যবহার বিধি রয়েছেঃ

  • একটি প্রভাইডার এর ভ্যালু ধারণ এবং এটির বদলানো লিসেন করা, যাতে যখন ভ্যালু বদলায়, তখন এই উইজেটটি বা প্রভাইডার যেটি এই ভ্যালুতে সাবস্ক্রাইবড আছে ওটি রিবিল্ড হবে। এটি করা যাবে ref.watch দিয়ে.
  • একটি প্রভাইডার এ লিসেনার এড করার মাধ্যমে, যাতে যেখনো একটি একশ্যান নেওয়া যায় যখন প্রভাইডারটি বদলায়। এটি করা যাবে ref.listen দিয়ে.
  • একটি প্রভাইডার এর শুধু ভ্যালু ধারণ করা একইসাথে বদলানোকে এড়িয়ে যাওয়া এটি খুবি উপকারী যখন আমাদের প্রভাইডার এর শুধু একটি ভ্যালু প্রয়োজন হয়, কোন ইভেন্ট কলব্যাক ফাংশন এ, যেমন একটি onPressed কলব্যাক ফাংশন। এটি করা যাবে ref.read দিয়ে.
note

যখনি সম্ভব, চাইবেন ref.watch ব্যবহার করতে ref.read অথবা ref.listen এর পরিবর্তে একটি ফিচার ইমপ্লিমেন্ট করার জন্যে। আপনার ইমপ্লিমেন্টেশন ref.watch এ পরিবর্তন করার পর, এটি একইসাথে রিএক্টিভ এবং ডিক্লেরাটিভ হয়ে যায়, যেটি আপনার এপ্লিক্যাশন আরো মেইন্টেইনেভেল বানাই।

ref.watch দিয়ে একটি প্রভাইডার অবসার্ব করা

ref.watch কে একটি উইজেট এর build মেথড এর ভিতর অথবা একটি প্রভাইডার এর বডির ভিতরে ব্যবহার করা যায়, যাতে আমরা ওই উইজেট/প্রভাইডার থেকে ref.watch কল ব্যবহার করে এই কলের প্রভাইডার অবসার্ব করতে পারি:

উদাহরণসরূপ, একটি প্রভাইডার ref.watch ব্যবহার করে একাধিক প্রভাইডার একত্রে করে একটি নতুন ভ্যালুতে রূপান্তর করতে পারে।

একটি উদাহারণ হবে একটি টুডু-লিস্ট ফিলটার করা।

আমাদের দুইটি প্রভাইডার থাকতে পারে:

  • filterTypeProvider, একটি প্রভাইডার যা বর্তমানের ফিলটার টাইপ এক্সপোস করে। যেমনঃ (none, show only completed tasks, ...)
  • todosProvider, একটি প্রভাইডার যা সকল টুডুলিস্ট এক্সপোস করে

এবং ref.watch ব্যবহার করে,আমরা একটি তৃতীয় প্রভাইডার বানাতে পারি উপরোক্ত দুইটি প্রভাইডার ব্যবহার করে এবং এটি আমাদের একটি ফিলটার করা টুডু লিস্ট দিবেঃ


final filterTypeProvider = StateProvider<FilterType>((ref) => FilterType.none);
final todosProvider =
StateNotifierProvider<TodoList, List<Todo>>((ref) => TodoList());

final filteredTodoListProvider = Provider((ref) {
// ফিল্টার করা এবং সকল টুডু গুলা ধারণ করুন
final FilterType filter = ref.watch(filterTypeProvider);
final List<Todo> todos = ref.watch(todosProvider);

switch (filter) {
case FilterType.completed:
// কমপ্লিটেড সব টুডু রিটার্ন করবে
return todos.where((todo) => todo.isCompleted).toList();
case FilterType.none:
// আনফিল্টারড সব টুডু গুলা রিটার্ন করবে
return todos;
}
});

এই কোড দ্বারা, filteredTodoListProvider এখন ফিল্টার করা টুডু এক্সপোস করে.

ফিল্টার করা লিস্টও স্বয়ংক্রিয়ভাবে আপডেট হবে যদি ফিল্টার বা টুডুর তালিকা পরিবর্তিত হয়। তবুও একই সময়ে, ফিল্টার করা তালিকাটি পুনরায় গণনা করা হবে না যদি ফিল্টার বা কাজের তালিকা কোনটিই পরিবর্তন না হয়।

একই ভাবে, একটি উইজেট ref.watch ব্যবহার করে একটি ইউজার ইন্টারফেস দেখাতে পারে যেটি প্রভাইডার এর উপর ডিপেন্ডেডঃ


final counterProvider = StateProvider((ref) => 0);

class HomeView extends ConsumerWidget {
const HomeView({super.key});


Widget build(BuildContext context, WidgetRef ref) {
// ref ব্যবহার করে একটি প্রভাইডার অবসার্ব করা হচ্ছে
final counter = ref.watch(counterProvider);

return Text('$counter');
}
}

এই কোড স্নিপেট হতে আমরা দেখতে পাচ্ছি, এখানে একটি উইজেট একটি প্রভাইডার অবসার্ব করতেছে যেটি একটি কাউন্টার স্টোর করে, এবং যদি কাউন্টারটি পরিবর্তিত হয়, তাহলে এই উইজেটটি রিবিল্ড হবে এবং ইউয়াই ও পরিবর্তন হবে নতুন ভ্যালু এর সাথে।

caution

মনে রাখতে হবেঃ watch মেথড এসোঙ্ক্রোনাসলি (asynchronously) কল করা যাবে না। যেমন একটি ElevatedButton এর onPressed কলব্যাকে. এবং initState এর ভিতর আর State এর লাইফসাইকেলে ও ব্যবহার করা যাবে না।

ওসবক্ষেত্রে, ref.read ব্যবহার করতে পারেন।

ref.listen ব্যবহার করে প্রভাইডার এর পরিবর্তনে রিএক্ট করা

একইভাবে ref.watch এর মত, ref.listen ব্যবহার করেও আমরা একটি প্রভাইডার অবসার্ব করতে পারব।

তাদের মধ্যে মূল পার্থক্য হচ্ছে, যে প্রভাইডারটি লিসেন করা হচ্ছে সেটার ভ্যালু পরবির্তন হলে এটি উইজেট/প্রভাইডার রিবিল্ড না করে, ref.listen একটি কাস্টম ফাংশন কল করে।

এটি অনেকক্ষেত্রে ব্যবহারযোগ্য হতে পারে যখন কোন পরিবর্তন হয়, যেমন একটি স্ন্যাকবার দেখানো যখন কোন ত্রুটি বা এরর আসে বা হয়।

ref.listen মেথড এর জন্য 2টি অবস্থানগত আর্গুমেন্টের প্রয়োজন, প্রথমটি হল প্রভাইডার এবং দ্বিতীয়টি হল কলব্যাক ফাংশন যা আমরা স্টেট পরিবর্তনের সময় কার্যকর করতে চাই৷

কলব্যাক ফাংশন যখন কল করা হয় তখন 2টি ভ্যালু পাওয়া যাবে, পূর্ববর্তী স্টেটের ভ্যালু এবং নতুন স্টেটের ভ্যালু।

ref.listen মেথডটি একটি প্রভাইডার এর বডিতে ও ব্যবহার করা যাবেঃ


final counterProvider = StateNotifierProvider<Counter, int>(Counter.new);

final anotherProvider = Provider((ref) {
ref.listen<int>(counterProvider, (int? previousCount, int newCount) {
print('The counter changed $newCount');
});
// ...
});

অথবা একটি উইজেট এর build মেথড এ:


final counterProvider = StateNotifierProvider<Counter, int>(Counter.new);

class HomeView extends ConsumerWidget {
const HomeView({super.key});


Widget build(BuildContext context, WidgetRef ref) {
ref.listen<int>(counterProvider, (int? previousCount, int newCount) {
print('The counter changed $newCount');
});

return Container();
}
}
caution

listen মেথড এসোঙ্ক্রোনাসলি (asynchronously) কল করা যাবে না, যেমন একটি ElevatedButton এর onPressed কলব্যাকে. এবং initState এর ভিতর আর State এর লাইফসাইকেলে ও ব্যবহার করা যাবে না।

Using ref.read to obtain the state of a provider once

ref.read মেথড হল কোনো একটি প্রভাইডারের অবস্থা ধারণ করা, অতিরিক্ত কোনো কিছু ছাড়াই।

এটি সাধারণত ব্যবহার করা হয় সেই ফাংশনগুলোতে যেগুলা ইউজাররা ইন্টারেকশেন দ্বারা ট্রিগ্রার হয়। উদাহরণস্বরূপ, যখন একজন ব্যবহারকারী একটি বাটনে ক্লিক করেন তখন আমরা একটি কাউন্টার বৃদ্ধি করতে ref.read ব্যবহার করতে পারিঃ


final counterProvider =
StateNotifierProvider<Counter, int>(Counter.new);

class HomeView extends ConsumerWidget {
const HomeView({super.key});


Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
// `increment()` কল করি `Counter` ক্লাস এর মধ্যে
ref.read(counterProvider.notifier).increment();
},
),
);
}
}
note

ref.read যত পারা যায় তত কম ইউজ করা ভাল.

এটি বিদ্যমান কারণ অনেক সময় watch অথবা listen ব্যবহার করা অনেক বেশি অসুবিধাজনক হবে, সেইসব জায়গায় এটি ব্যবহার করুন।

যদি আপনি পারেন, এটি প্রায় সবসময় ভাল হবে watch/listen ব্যবহার করা, বিশেষ করে watch.

কখনো ref.read বিল্ড মেথড এ ব্যবহার করবেন না

আপনি একটি উইজেটের কর্মক্ষমতা অপ্টিমাইজ করতে ref.read ব্যবহার করতে প্রলুব্ধ হতে পারেন নিচের মতঃ


final counterProvider = StateProvider((ref) => 0);

Widget build(BuildContext context, WidgetRef ref) {
// "read" ব্যবহার করুন একটি প্রভাইডার এর আপডেট এড়িয়ে যাওয়ার জন্যে
final counter = ref.read(counterProvider.notifier);
return ElevatedButton(
onPressed: () => counter.state++,
child: const Text('button'),
);
}

কিন্তু এটি একটি খুব খারাপ অভ্যাস এবং এর কারণে এমন বাগ হতে পারে যা ট্র্যাক করা কঠিন।

এইভাবে ref.read ব্যবহার করা সাধারণত এই চিন্তার সাথে যুক্ত হয় "কোনও প্রভাইডার দ্বারা প্রকাশিত ভ্যালু কখনই পরিবর্তিত হয় না তাই ref.read ব্যবহার করা নিরাপদ"। এই অনুমানের সাথে সমস্যাটি হল যে, যদিও আজ সেই প্রভাইডার প্রকৃতপক্ষে তার মান আপডেট করতে পারে না, কোন গ্যারান্টি নেই যে আগামীকাল একই হবে।

সফ্টওয়্যার অনেক পরিবর্তন হতে থাকে, এবং সম্ভবত ভবিষ্যতে, এমন একটি ভ্যালু যা আগে কখনও পরিবর্তিত হয়নি তা পরিবর্তন করতে হবে। কিন্তু যদি আপনি ref.read ব্যবহার করেন, যখন সেই ভ্যালু পরিবর্তন হতে শুরু করে, তখন আপনার সম্পূর্ণ কোডবেসের মধ্যে ref.read কে ref.watch-এ পরিবর্তন করতে হবে - যা ত্রুটি প্রবণ এবং কিছু ক্ষেত্রে আপনি ভুলে যাওয়ার সম্ভাবনা রয়েছে।

আপনি যদি শুরুতে ref.watch ব্যবহার করেন তবে আপনার কোনো সমস্যা হবে না।

কিন্তু আমি আমার উইজেট রিবিল্ড সংখ্যা কমাতে ref.read ব্যবহার করতে চেয়েছিলাম

লক্ষ্যটি প্রশংসনীয় হলেও, এটা মনে রাখা গুরুত্বপূর্ণ যে আপনি এর পরিবর্তে ref.watch ব্যবহার করে ঠিক একই প্রভাব (বিল্ডের সংখ্যা হ্রাস) অর্জন করতে পারেন।

প্রভাইডাররা পুনর্নির্মাণের সংখ্যা হ্রাস করার সময় একটি ভ্যালু প্রাপ্ত করার বিভিন্ন উপায় অফার করে, যা আপনি এর পরিবর্তে ব্যবহার করতে পারেন।

উদাহরণস্বরূপ এর পরিবর্তে


final counterProvider = StateProvider((ref) => 0);

Widget build(BuildContext context, WidgetRef ref) {
StateController<int> counter = ref.read(counterProvider.notifier);
return ElevatedButton(
onPressed: () => counter.state++,
child: const Text('button'),
);
}

আমরা করতে পারি:


final counterProvider = StateProvider((ref) => 0);

Widget build(BuildContext context, WidgetRef ref) {
StateController<int> counter = ref.watch(counterProvider.notifier);
return ElevatedButton(
onPressed: () => counter.state++,
child: const Text('button'),
);
}

উভয় স্নিপেট একই প্রভাব অর্জন করে: কাউন্টার বৃদ্ধি পেলে আমাদের বাটনটি পুনর্নির্মাণ করবে না।

অন্যদিকে, দ্বিতীয় পদ্ধতিটি এমন ক্ষেত্রে সমর্থন করে যেখানে কাউন্টারটি পুনরায় সেট করা হয়েছে। উদাহরণস্বরূপ, অ্যাপ্লিকেশনটির অন্য একটি অংশ কল করতে পারেঃ

ref.refresh(counterProvider);

যেটি আবার StateController অবজেক্টটি তৈরি করবে.

If we used ref.read here, our button would still use the previous StateController instance, which was disposed and should no longer be used. Whereas using ref.watch correctly rebuilt the button to use the new StateController.

যদি আমরা এখানে ref.read ব্যবহার করি, আমাদের বাটনটি এখনও পূর্ববর্তী StateController এর ইন্সট্যান্স ব্যবহার করবে, যা নিষ্পত্তি করা হয়েছে এবং আর ব্যবহার করা উচিত নয়। যেখানে ref.watch ব্যবহার করে নতুন StateController ব্যবহার করার জন্য বাটনটি সঠিকভাবে পুনর্নির্মাণ করা হয়েছে।

কি Read করতে হবে সিদ্ধান্ত নেয়া

তা আপনি যে প্রভাইডার রিড করতে চান তার উপর নির্ভর করে, আপনার একাধিক সম্ভাব্য ভ্যালু থাকতে পারে যা আপনি রিড করতে পারেন।

একটি উদাহরণ হিসাবে, নিম্নলিখিত StreamProvider বিবেচনা করুনঃ

final userProvider = StreamProvider<User>(...);

যখন আপনি userProvider রিড করবেন, আপনিঃ

  • সিঙ্ক্রোনাসলি বর্তমান স্টেট রিড করতে পারবেন userProvider লিসেন করে:

    Widget build(BuildContext context, WidgetRef ref) {
    AsyncValue<User> user = ref.watch(userProvider);

    return user.when(
    loading: () => const CircularProgressIndicator(),
    error: (error, stack) => const Text('Oops'),
    data: (user) => Text(user.name),
    );
    }
  • সংযোক্ত Stream টি ধারণ করে, userProvider.stream লিসেন করে:

    Widget build(BuildContext context, WidgetRef ref) {
    Stream<User> user = ref.watch(userProvider.stream);
    }
  • একটি Future ধারণ করে যা নতুন নির্গত ভ্যালু দ্বারা রিসল্ভ করে,userProvider.future লিসেন করেঃ

    Widget build(BuildContext context, WidgetRef ref) {
    Future<User> user = ref.watch(userProvider.future);
    }

অন্যান্য প্রভাইডার বিভিন্ন বিকল্প ভ্যালু অফার করতে পারে. আরও তথ্যের জন্য, প্রতিটি প্রভাইডার এর API reference পড়ুন.

"select" দিয়ে রিবিল্ড ফিলটার করা

উল্লেখ করার মত, রিডিং প্রভাইডার এর সাথে সম্পর্কিত একটি চূড়ান্ত ফিচার হল, একটি উইজেট/প্রোভাইডার রিবিল্ড সংখ্যা বা কতবার ref.listen একটি ফাংশন নির্বাহ করে তা হ্রাস করার ক্ষমতা।

This is important to keep in mind as, by default, listening to a provider listens to the entire object. But in some cases, a widget/provider may only care about some properties instead of the whole object.

ডিফল্টরূপে, প্রভাইডার রিড করার জন্য এটি মনে রাখা গুরুত্বপূর্ণ যে পুরো প্রভাইডার রিড করে। কিন্তু কিছু ক্ষেত্রে, একটি উইজেট/প্রোভাইডার পুরো বস্তুর পরিবর্তে শুধুমাত্র কিছু বৈশিষ্ট্যে গুরুত্ব দেই।

উদাহরণস্বরূপ, একজন প্রভাইডার একটি User এক্সপোস করতে পারেঃ

abstract class User {
String get name;
int get age;
}

কিন্তু একটি উইজেট শুধুমাত্র User নাম ব্যবহার করতে পারেঃ

Widget build(BuildContext context, WidgetRef ref) {
User user = ref.watch(userProvider);
return Text(user.name);
}

আমরা যদি সহজভাবে ref.watch ব্যবহার করি, তাহলে User এর age পরিবর্তিত হলে এটি উইজেটটিকে পুনর্নির্মাণ করবে।

সমাধান হল রিভারপডকে স্পষ্টভাবে বলার জন্য select ব্যবহার করা যে আমরা শুধুমাত্র User এর কিছু বৈশিষ্ট্য শুনতে চাই।

আপডেট করা কোড হবেঃ

Widget build(BuildContext context, WidgetRef ref) {
String name = ref.watch(userProvider.select((user) => user.name));
return Text(name);
}

এটি যেভাবে কাজ করে তা হল, select ব্যবহার করে, আমরা এমন একটি ফাংশন নির্দিষ্ট করছি যা আমাদের নির্ধারণ করে প্রাপার্টি প্রদান করে।

তারপর, যখনই User পরিবর্তন হবে, রিভারপড এই ফাংশনটিকে কল করবে এবং আগের এবং নতুন ফলাফলের তুলনা করবে। যদি তারা আলাদা হয় (যেমন নাম পরিবর্তন হলে), রিভারপড উইজেটটি পুনর্নির্মাণ করবে। কিন্তু যদি তারা সমান হয় (যেমন যখন শুধুমাত্র বয়স পরিবর্তিত হয়), তাহলে রিভারপড উইজেটটি পুনর্নির্মাণ করবে না।

info

ref.listen এর সাথেও select ব্যবহার করা সম্ভবঃ

ref.listen<String>(
userProvider.select((user) => user.name),
(String? previousName, String newName) {
print('The user name changed $newName');
}
);

এমন করলে নাম পরিবর্তন হলেই শুধু লিসেনার কল হবে।

tip

আপনাকে অবজেক্ট এর প্রপার্টি ফেরত দিতে হবে না। যে কোনো ভ্যালু এর overrides == কাজ করবে। উদাহরণস্বরূপ, আপনি করতে পারেন:

final label = ref.watch(userProvider.select((user) => 'Mr ${user.name}'));