StateNotifierProvider는 (Riverpod가 다시 익스포트한 state_notifier 패키지에서) StateNotifier를 수신하고 노출하는 데 사용되는 provider입니다.
일반적으로 다음과 같은 용도로 사용됩니다:
- 사용자 지정 이벤트에 반응한 후 시간이 지남에 따라 변경될 수 있는 불변 상태를 노출합니다.
- 일부 상태를 수정하는 로직(일명 '비즈니스 로직')을 한 곳에 집중화하여 시간이 지남에 따라 유지보수성을 개선합니다.
INFO)
대신 NotifierProvider를 사용하는 것이 좋습니다.
예시로 StateNotifierProvider를 사용하여 할 일 목록을 구현할 수 있습니다. 이렇게 하면 UI가 사용자 상호작용에 따라 할 일 목록을 수정할 수 있도록 addTodo와 같은 메서드를 노출할 수 있습니다:
// The state of our StateNotifier should be immutable.
// We could also use packages like Freezed to help with the implementation.
@immutable
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();
});
'Flutter > Package' 카테고리의 다른 글
Flutter Riverpod All Providers (5-5) - StreamProvider (0) | 2023.07.17 |
---|---|
Flutter Riverpod All Providers (5-4) - FutureProvider (0) | 2023.07.17 |
Flutter Riverpod All Providers (5-2) - (Async)NotifierProvider (0) | 2023.07.16 |
Flutter Riverpod All Providers (5-1) - Provider (0) | 2023.07.16 |
Flutter Riverpod 상태관리 (4) - Code generation 대해 (0) | 2023.07.16 |