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

Flutter Riverpod All Providers (5-7) - ChangeNotifierProvider

· 댓글개 · Dev_Whale

ChangeNotifierProvider(flutter_riverpod/hooks_riverpod만 해당)는 Flutter 자체에서 변경 알림을 수신하고 노출하는 데 사용되는 Provider입니다.

 

ChangeNotifierProvider를 사용하는 것은 Riverpod에서 권장하지 않으며 주로 다음과 같은 용도로 존재합니다:

  • package:provider에서 ChangeNotifierProvider를 사용할 때 쉽게 전환할 수 있습니다.
  • 불변 상태가 선호되지만 변경 가능한 상태를 지원합니다.
INFO)
ChangeNotifierProvider 대신 NotifierProvider를 사용하는 것이 좋습니다.
변경 가능한 상태를 확실히 원하는 경우에만 ChangeNotifierProvider를 사용하는 것이 좋습니다.

때로는 불변 상태 대신 변경 가능한 상태를 사용하는 것이 더 효율적일 수 있습니다. 단점은 유지 관리가 더 어렵고 다양한 기능이 손상될 수 있다는 점입니다.

예를 들어, state가 변경 가능한 상태이면 select가 값이 변경되지 않은 것으로 간주하므로 provider.select를 사용하여 위젯의 리빌드를 최적화하는 것이 작동하지 않을 수 있습니다.

따라서 불변 데이터 구조를 사용하는 것이 때때로 더 빠를 수 있습니다. 따라서 사용 사례에 맞는 벤치마크를 만들어 ChangeNotifierProvider를 사용함으로써 실제로 성능이 향상되는지 확인하는 것이 중요합니다.

 

사용 예시로 ChangeNotifierProvider를 사용하여 할 일 목록을 구현할 수 있습니다. 이렇게 하면 addTodo와 같은 메서드를 노출하여 UI가 사용자 상호작용에 따라 할 일 목록을 수정할 수 있습니다:

class Todo {
  Todo({
    required this.id,
    required this.description,
    required this.completed,
  });

  String id;
  String description;
  bool completed;
}

class TodosNotifier extends ChangeNotifier {
  final todos = <Todo>[];

  // Let's allow the UI to add todos.
  void addTodo(Todo todo) {
    todos.add(todo);
    notifyListeners();
  }

  // Let's allow removing todos
  void removeTodo(String todoId) {
    todos.remove(todos.firstWhere((element) => element.id == todoId));
    notifyListeners();
  }

  // Let's mark a todo as completed
  void toggle(String todoId) {
    final todo = todos.firstWhere((todo) => todo.id == todoId);
    todo.completed = !todo.completed;
    notifyListeners();
  }
}

// 마지막으로, UI가 TodosNotifier 클래스와 상호 작용할 수 있도록 
// ChangeNotifierProvider를 사용하고 있습니다.
final todosProvider = ChangeNotifierProvider<TodosNotifier>((ref) {
  return TodosNotifier();
});

이제 ChangeNotifierProvider를 정의했으므로 이를 사용하여 UI의 할 일 목록과 상호 작용할 수 있습니다:

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

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // rebuild the widget when the todo list changes
    List<Todo> todos = ref.watch(todosProvider).todos;

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

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