
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