riverpod의 provider 사용
안녕하세요 선생님 !!
강의 잘보고 있습니다.
Provider : 수신측에 변경 사항을 알리지 않음 라고 하셔서
코드를 작성해보았습니다.
countprovider안에서 ref.watch(towProvider) 사용해봤는데요
우선 여기서 watch를 써서 상태가 바뀐건 이해합니다.
그래서 "counter 생성자" 가 계속 출력되고요 .
근데 main함수에서 counterProvider 를 ref.watch했는데 화면이 계속 갱신 되는 건 이해가 가지 않습니다.
수신측에 변경 사항을 알리지 않음 이라고 하셔서 여기서는 호출해도 변함이 없겠구나 라고 생각했습니다...
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final towProvider= NotifierProvider<Two, int>(
(){return Two();}
);
final counterProvider = Provider<Counter>((ref) {
print("hello");
int num=ref.watch(towProvider);
return Counter(num:num);});
class Two extends Notifier<int>{
Two(){
print("Two 생성자");
}
@override
int build() => 0;
int add() => state++;
}
class Counter {
Counter ({required this.num}){
print("Counter 생성자");
}
int num;
int getIncreasedNumber() => num ++;
}
void main() {
runApp(
const ProviderScope(
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
),
),
);
}
class MyApp extends ConsumerWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
print("build");
Counter counter = ref.watch(counterProvider);
return Scaffold(
body: Center(
child: Text(
"${counter.num}",
style: const TextStyle(
fontSize: 24,
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: (){ref.read(towProvider.notifier).add();},
child: const Icon(Icons.add),
),
);
}
}
답변 1
1
안녕하세요 유하님
ref.watch는 Provider에서 전달받은 상태가 변경되는 경우 위젯을 rebuild를 하는 방식으로 동작합니다.

Provider 자체는 내부적으로 상태가 갱신될 일이 없기 때문에 ref.watch로 접근해도 화면이 갱신될 일이 없는게 맞으며 이 부분을 강의에선 변경사항을 알리지 못한다고 표현하였습니다. 하지만 아래와 같이 ref.watch에 의해서 매번 새로운 Counter 인스턴스가 반환되는 경우 화면이 갱신되는게 맞습니다.
final counterProvider = Provider<Counter>((ref) {
int num = ref.watch(towProvider);
return Counter(num:num);
});
감사합니다 :)
1
아하 감사합니다.
그럼 추가적으로 궁금한 것이 생겼습니다.
새로운 Counter 인스턴스가 반환되서 => 갱신되는 거라고 하셨는데
다시 ref.watch를 빼고 다시 실행했을때는, 어떻게 보면 이때도 새로운 인스턴스가 반환되는 것 아닌가요? 앞에 const 키워드를 붙이지 않아서요... !
final counterProvider = Provider<Counter>((ref) {
print("hello");
return Counter();});
2
ref.watch(counterProvider)를 호출하는 경우, 무조건 Counter() 인스턴스를 새롭게 만들어서 반환하는 방식으로 동작하지 않습니다. 첫 호출시에만 Counter()를 생성해서 내부적으로 들고 있고, 이후에 요청이 들어오면 내부적으로 변경 사항이 없는 경우 처음에 만들어둔 객체를 그대로 반환합니다. 공식 문서에선 캐싱 기능이라고 표현합니다. (autoDispose로 생성하는 경우에는 해당 Provider에 대한 참조가 없다면 제거될 수 있습니다. 자세한 사항은 공식 문서를 참고해 주세요.)
Provider<Counter>는 내부에 상태가 없기 때문에 자체적으로 상태 변화를 일으킬 수 없으므로 Provider 내부에 ref.watch가 없다면 한 번 생성한 객체를 계속 들고 있으며 변경된 값을 반환할 수 없습니다.
수강 기한 연장 요청드려도될까요..
1
48
2
37.provider 실습 문제점, 카트에서 상품이 지워지지 않습니다.
1
75
2
다트 프로젝트
1
51
2
context.read<LangService>().toggleLang 해도 언어가 변경되는 이유
1
74
3
수강 기간 연장 신청 요청드립니다.
1
68
3
수강기간 연장 부탁드립니다.
1
58
3
제공해주신 flutter_design_system 라이브러리 질문입니다.
1
53
2
수강 기간 연장 부탁드립니다
1
52
2
수강 기한 연장
1
78
3
강의 잘 보고있습니다!
1
59
2
애뮬레이터 실행 오류
1
69
2
pdf 강의노트
1
62
2
수강기간 연장 부탁드립니다.
1
86
2
수강 기간 연장 요청
1
86
2
수강기간 연장 부탁드립니다
1
129
2
코드 생성기 - build runner 관련 오류
1
110
1
디자인 시스템 구성에 대해 질문 드립니다
2
145
2
CartItem 추가시
1
95
2
const 커스텀클래스
1
95
1
강의 수강 기간 연장 요청드립니다.
1
127
2
코드 생성기 - 실습 build runner 안 되는 분.
1
270
2
Flutter 강의자료 열리지 않는 문제
1
165
2
riverpod 프로젝트에 궁금한점이 있어 질문 남깁니다.
1
123
2
수강 기강 연장 부탁드리겠습니다! :ㅇ
1
88
2





