StateNotifierProvider
StateNotifierProvider
হল একটি প্রভাইডার যা একটি StateNotifier (প্যাকেজ state_notifier থেকে, যা রিভারপড পুনরায় রি-এক্সপোর্ট করে) রিড এবং এক্সপোস করতে ব্যবহৃত হয়।
StateNotifier এর সাথে StateNotifierProvider
হল স্ট্যাট পরিচালনার জন্য রিভারপডের প্রস্তাবিত সমাধান যা ব্যবহারকারীর ইন্টারঅ্যাকশনের প্রতিক্রিয়ায় পরিবর্তিত হতে পারে।
এটি সাধারণত এর জন্য ব্যবহৃত হয়:
- একটি অপরিবর্তনীয় অবস্থা এক্সপোস করা যা কাস্টম ইভেন্টগুলিতে প্রতিক্রিয়া করার পরে সময়ের সাথে সাথে পরিবর্তিত হতে পারে।
- একটি একক জায়গায় কিছু অবস্থা (ওরফে "বিজনেস লজিক") সংশোধন করার জন্য লজিককে কেন্দ্রীভূত করা, সময়ের সাথে সাথে রক্ষণাবেক্ষণযোগ্যতা উন্নত করা।
ব্যবহারের উদাহরণ হিসাবে, আমরা একটি টুডু তালিকা বাস্তবায়ন করতে StateNotifierProvider
ব্যবহার করতে পারি।
এটি করার ফলে ব্যবহারকারীর ইন্টারঅ্যাকশনে UI-কে টুডুর তালিকা পরিবর্তন করতে দেওয়ার জন্য addTodo
-এর মতো মেথডগুলোকে এক্সপোস করার অনুমতি দেওয়া হবে:
// The state of our StateNotifier should be immutable.
// We could also use packages like Freezed to help with the implementation.
class Todo {
const Todo({required this.id, required this.description, required this.completed});
// All properties should be `final` on our class.
final String id;
final String description;
final bool completed;
// Since Todo is immutable, we implement a method that allows cloning the
// Todo with slightly different content.
Todo copyWith({String? id, String? description, bool? completed}) {
return Todo(
id: id ?? this.id,
description: description ?? this.description,
completed: completed ?? this.completed,
);
}
}
// The StateNotifier class that will be passed to our StateNotifierProvider.
// This class should not expose state outside of its "state" property, which means
// no public getters/properties!
// The public methods on this class will be what allow the UI to modify the state.
class TodosNotifier extends StateNotifier<List<Todo>> {
// We initialize the list of todos to an empty list
TodosNotifier(): super([]);
// Let's allow the UI to add todos.
void addTodo(Todo todo) {
// Since our state is immutable, we are not allowed to do `state.add(todo)`.
// Instead, we should create a new list of todos which contains the previous
// items and the new one.
// Using Dart's spread operator here is helpful!
state = [...state, todo];
// No need to call "notifyListeners" or anything similar. Calling "state ="
// will automatically rebuild the UI when necessary.
}
// Let's allow removing todos
void removeTodo(String todoId) {
// Again, our state is immutable. So we're making a new list instead of
// changing the existing list.
state = [
for (final todo in state)
if (todo.id != todoId) todo,
];
}
// Let's mark a todo as completed
void toggle(String todoId) {
state = [
for (final todo in state)
// we're marking only the matching todo as completed
if (todo.id == todoId)
// Once more, since our state is immutable, we need to make a copy
// of the todo. We're using our `copyWith` method implemented before
// to help with that.
todo.copyWith(completed: !todo.completed)
else
// other todos are not modified
todo,
];
}
}
// Finally, we are using StateNotifierProvider to allow the UI to interact with
// our TodosNotifier class.
final todosProvider = StateNotifierProvider<TodosNotifier, List<Todo>>((ref) {
return TodosNotifier();
});
এখন যেহেতু আমরা একটি StateNotifierProvider
সংজ্ঞায়িত করেছি, আমরা এটি ব্যবহার করতে পারি আমাদের UI-তে todos তালিকার সাথে ইন্টারঅ্যাক্ট করতেঃ
class TodoListView extends ConsumerWidget {
const TodoListView({super.key});
Widget build(BuildContext context, WidgetRef ref) {
// rebuild the widget when the todo list changes
List<Todo> todos = ref.watch(todosProvider);
// Let's render the todos in a scrollable list view
return ListView(
children: [
for (final todo in todos)
CheckboxListTile(
value: todo.completed,
// When tapping on the todo, change its completed status
onChanged: (value) => ref.read(todosProvider.notifier).toggle(todo.id),
title: Text(todo.description),
),
],
);
}
}