1. RiverPod가 vm이 되어 상태 관리하기
- 상태를 외부에서 관리함
- 외부에 클래스로 따로 만들어서 상태를 가지고 있고 화면은 컨슈머(소비자)
- 상태를 변경하면 변경된 부분만 리로드됨
- 컨슈머들은 상태를 구독하고 있음
- 메서드 : 퍼블리셔 → 상태 데이터가 변경됨
2. 기본 셋팅하기
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: TodoPage(), ); } } class TodoPage extends StatelessWidget { const TodoPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Text( "완료 : true, 내용 : 공부하기", style: TextStyle(fontSize: 30), ), ), ); } }
3. 기본 provider - 데이터를 관리 / Session처럼 사용
- 관리할 데이터를 제네릭으로 넣어주기
- return되면 데이터가 창고안에서 관리
- 창고에 직접적인 접근은 불가능함 → 창고 관리자를 통해서만 접근이 가능
상태 변경 불가
- 최초에 read할때만 그림이 그려짐
- 데이터를 바꿀 순 있으나 다시 그림이 그려지지 않음
// 창고 데이터 import 'package:flutter_riverpod/flutter_riverpod.dart'; class Todo{ bool isCompleted; String description; Todo(this.isCompleted, this.description); } // 창고 관리자 : 창고 데이터 관리 final todoProvider = StateProvider<Todo>((ref) { // 관리할 데이터를 제네릭으로 넣어주기 return Todo(true, "공부하기"); });
- 모든 트리에 정점 -> 모든 트리에 접근 가능
- 상태에 창고 관리자를 통해 접근 가능
- READ
- REF가 있어야 창고 관리자에 접근 가능
- 창고 데이터를 한번만 수신함 → 상태 변경을 확인 안함
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod_01/todo.dart'; void main() { runApp( ProviderScope(child: MyApp()) // 모든 트리에 정점 -> 모든 트리에 접근 가능 ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { // REF가 있어야 창고 관리자에 접근 가능 // 창고 데이터를 한번만 수신함 → 상태 변경을 확인 안함 return MaterialApp( home: TodoPage(), ); } } class TodoPage extends ConsumerWidget { // 상태에 창고관리자를 통해 접근 가능 const TodoPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { Todo todo = ref.read(todoProvider); return Scaffold( body: Center( child: Text( "완료 : ${todo.isCompleted}, 내용 : ${todo.description}", style: TextStyle(fontSize: 30), ), ), ); } }
- 재실행해 함!
4. VM만들기
- 창고 관리하기
- 자식은 부모 것을 쓸 수 있으니 super를 안 적어도 됨
// 창고 데이터 import 'package:flutter_riverpod/flutter_riverpod.dart'; class Todo{ bool isCompleted; String description; Todo(this.isCompleted, this.description); } // 창고 - 창고 데이터를 상속해서 가지고 있음 class TodoVM extends Todo{ // todo를 상속 TodoVM(super.isCompleted, super.description); } // 창고 관리자 : 창고 관리 final todoProvider = StateProvider<TodoVM>((ref) { // 관리할 데이터를 제네릭으로 넣어주기 return TodoVM(true, "공부하기"); });
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod_01/todo.dart'; void main() { runApp( ProviderScope(child: MyApp()) // 모든 트리에 정점 -> 모든 트리에 접근 가능 ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { // REF가 있어야 창고 관리자에 접근 가능 // 창고 데이터를 한번만 수신함 → 상태 변경을 확인 안함 return MaterialApp( home: TodoPage(), ); } } class TodoPage extends ConsumerWidget { // 상태에 창고관리자를 통해 접근 가능 const TodoPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { TodoVM vm = ref.read(todoProvider); return Scaffold( body: Center( child: Text( "완료 : ${vm.isCompleted}, 내용 : ${vm.description}", style: TextStyle(fontSize: 30), ), ), ); } }
- 데이터 가공하기
// 창고 데이터 import 'package:flutter_riverpod/flutter_riverpod.dart'; class Todo{ bool isCompleted; String description; Todo(this.isCompleted, this.description); } // 창고 - 창고 데이터를 상속해서 가지고 있음 class TodoVM extends Todo{ // todo를 상속 TodoVM(super.isCompleted, super.description); String getCompleted(){ // 창고 데이터 가공 return isCompleted ? "완료" : "미완료"; } } // 창고 관리자 : 창고 관리 final todoProvider = StateProvider<TodoVM>((ref) { // 관리할 데이터를 제네릭으로 넣어주기 return TodoVM(true, "공부하기"); });
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod_01/todo.dart'; void main() { runApp( ProviderScope(child: MyApp()) // 모든 트리에 정점 -> 모든 트리에 접근 가능 ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { // REF가 있어야 창고 관리자에 접근 가능 // 창고 데이터를 한번만 수신함 → 상태 변경을 확인 안함 return MaterialApp( home: TodoPage(), ); } } class TodoPage extends ConsumerWidget { // 상태에 창고관리자를 통해 접근 가능 const TodoPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { TodoVM vm = ref.read(todoProvider); return Scaffold( body: Center( child: Text( "완료 : ${vm.getCompleted()}, 내용 : ${vm.description}", style: TextStyle(fontSize: 30), ), ), ); } }
- 값은 변경되나 그림이 다시 그려지진 않음
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod_01/todo.dart'; void main() { runApp( ProviderScope(child: MyApp()) // 모든 트리에 정점 -> 모든 트리에 접근 가능 ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: TodoPage(), ); } } @override Widget build(BuildContext context, WidgetRef ref) { // REF가 있어야 창고 관리자에 접근 가능 // 창고 데이터를 한번만 수신함 → 상태 변경을 확인 안함 TodoVM vm = ref.read(todoProvider); return Scaffold( body: Center( child: Text( "완료 : ${vm.getCompleted()}, 내용 : ${vm.description}", style: TextStyle(fontSize: 30), ), ), floatingActionButton: FloatingActionButton( onPressed: (){ vm.isCompleted = false; // 따로 만들어넣는게 좋음 print("완료 : ${vm.isCompleted}"); }, child: Text("값변경"), ), ); } }
- 추가 실습하기
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod_01/todo.dart'; void main() { runApp(ProviderScope(child: MyApp())); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: TodoPage(), ); } } class TodoPage extends StatelessWidget { TodoPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Top(), Bottom(), ], ), ), ); } } class Bottom extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { return Text( // 변수 선언 없이 바로 받기 "완료 : ${ref.read(todoProvider).isCompleted}, 내용 : x", style: TextStyle(fontSize: 30), ); } } class Top extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final vm = ref.read(todoProvider); // 변수 선언하고 받기 return Text( "완료 : ${vm.isCompleted}, 내용 : x", style: TextStyle(fontSize: 30), ); } }
Share article