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

.family

এটি পড়ার আগে, providers এবং কীভাবে সেগুলি পড়তে হয় সম্পর্কে পড়ার বিবেচনা করুন।

এই অংশে, আমরা .family প্রদানকারী মডিফায়ার সম্পর্কে বিস্তারিত আলোচনা করব।

.family সংশোধকের একটি উদ্দেশ্য আছে: বাহ্যিক ভ্যালু থেকে একটি প্রভাইডার তৈরি করা।

family-এর জন্য কিছু সাধারণ ব্যবহার-ক্ষেত্র হবেঃ

  • FutureProvider এর আইডি থেকে একটি Message আনতে .family এর সাথে সংযুক্ত করা
  • একটি প্রদানকারীর কাছে বর্তমান Locale পাস করা, যাতে আমরা অনুবাদগুলি পরিচালনা করতে পারি

ব্যবহারবিধি

families গুলা যেভাবে কাজ করে তা হল প্রভাইডারে একটি অতিরিক্ত প্যারামিটার যোগ করা। এই প্যারামিটার তারপর অবাধে কিছু স্টেট তৈরি করতে আমাদের প্রভাইডারে ব্যবহার করা যেতে পারে।

উদাহরণস্বরূপ, আমরা family আর FutureProvider একত্রিত করে একটি Message ফেচ করতে পারি এর ID ব্যবহার করেঃ

final messagesFamily = FutureProvider.family<Message, String>((ref, id) async {
return dio.get('http://my_api.dev/messages/$id');
});

তারপর, আপনার messagesFamily প্রভাইডারটি ব্যবহার করার সময়, সিনট্যাক্সটি সামান্য পরিবর্তিত হয়। স্বাভাবিক সিনট্যাক্স আর কাজ করবে নাঃ

Widget build(BuildContext context, WidgetRef ref) {
// Error – messagesFamily is not a provider
final response = ref.watch(messagesFamily);
}

পরিবর্তে, আমাদের messagesFamily-এ একটি প্যারামিটার পাস করতে হবেঃ

Widget build(BuildContext context, WidgetRef ref) {
final response = ref.watch(messagesFamily('id'));
}
info

একযোগে বিভিন্ন প্যারামিটার সহ একটি family ব্যবহার করা সম্ভব। উদাহরণস্বরূপ, আমরা একই সময়ে ফরাসি এবং ইংরেজি উভয় অনুবাদ পড়তে একটি titleFamily ব্যবহার করতে পারিঃ

@override
Widget build(BuildContext context, WidgetRef ref) {
final frenchTitle = ref.watch(titleFamily(const Locale('fr')));
final englishTitle = ref.watch(titleFamily(const Locale('en')));

return Text('fr: $frenchTitle en: $englishTitle');
}

প্যারামিটার সীমাবদ্ধতা

familiy-গুলা সঠিকভাবে কাজ করার জন্য, এটি গুরুত্বপূর্ণ যে একটি প্রভাইডারে পাস করা প্যারামিটারের জন্য একটি সামঞ্জস্যপূর্ণ hashCode এবং == থাকা দরকার।

আদর্শভাবে, প্যারামিটারটি হয় একটি আদিম হওয়া উচিত (bool/int/double/String), একটি কন্সটেন্ট (প্রভাইডার), বা একটি অপরিবর্তনীয় বস্তু যা == এবং hashCode ওভাররাইড করে।

autoDispose এর ব্যবহার করা উচিত যখন প্যারামিটারটি কন্সটেন্ট নয়:

আপনি আপনার প্রভাইডারের কাছে একটি সার্চ ফিল্ডের ইনপুট পাস করার জন্য families ব্যবহার করতে চাইতে পারেন। কিন্তু সেই ভ্যালুটি প্রায়শই পরিবর্তিত হতে পারে এবং কখনও পুনরায় ব্যবহার করা উচিত নয়। এটি মেমরি লিকের কারণ হতে পারে কারণ ডিফল্টরূপে, একটি প্রভাইডার কখনও ধ্বংস হয় না যদি আর ব্যবহার না করা হয়।

.family এবং .autoDispose উভয়ই ব্যবহার করে সেই মেমরি লিক ঠিক করেঃ

final characters = FutureProvider.autoDispose.family<List<Character>, String>((ref, filter) async {
return fetchCharacters(filter: filter);
});

একটি family-তে একাধিক প্যারামিটার পাস করা

একটি প্রভাইডারকে একাধিক মান পাস করার জন্য families-এ কোনও অন্তর্নির্মিত সমর্থন নেই৷

অন্যদিকে, সেই ভ্যালু যেকোনো কিছু হতে পারে (যতক্ষণ না এটি পূর্বে উল্লেখিত বিধিনিষেধের সাথে মেলে)।

This includes:

  • একটি tuple যা tuple হতে
  • Freezed দ্বারা জেনেরেটেড অবজেক্ট অথবা built_value
  • equatable ব্যবহার করা অবজেক্ট

এখানে Freezed এবং equatable ব্যবহার করে একটি উদাহরণ রয়েছে:

@freezed
abstract class MyParameter with _$MyParameter {
factory MyParameter({
required int userId,
required Locale locale,
}) = _MyParameter;
}

final exampleProvider = Provider.autoDispose.family<Something, MyParameter>((ref, myParameter) {
print(myParameter.userId);
print(myParameter.locale);
// userId/locale দিয়ে কিছু করুন
});

@override
Widget build(BuildContext context, WidgetRef ref) {
int userId; // userId অন্য কোথাও থেকে পড়ুন
final locale = Localizations.localeOf(context);

final something = ref.watch(
exampleProvider(MyParameter(userId: userId, locale: locale)),
);

...
}