본문으로 바로가기
  1. Home
  2. Flutter/Package
  3. Flutter Riverpod All Providers (5-3) - StateNotifierProvider

Flutter Riverpod All Providers (5-3) - StateNotifierProvider

· 댓글개 · Dev_Whale

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();
});
💬 댓글 개
이모티콘창 닫기
울음
안녕
감사해요
당황
피폐

이모티콘을 클릭하면 댓글창에 입력됩니다.