guricode

Consumer_Riverpod 본문

앱/Flutter&Dart

Consumer_Riverpod

agentrakugaki 2025. 8. 1. 20:48

Riverpod 처음 쓰면 Consumer, ref.watch(), ProviderScope() 이런 것들이 갑자기 쏟아져 나옴

Consumer란?

Consumer는 한마디로 말하면
“내가 Provider 상태값을 UI에 쓰고 싶을 때 그걸 감지해서 다시 그려주는 위젯”이다.

Flutter는 위젯이 상태값이 바뀌면 화면을 다시 그리는 구조야.
그럼 Riverpod으로 상태를 관리할 때,
“어떻게 상태가 바뀌었는지 감지해서 위젯을 다시 그릴까?”

→ 그걸 해주는 게 바로 Consumer다.


왜 필요한가?

StatelessWidget이나 StatefulWidget에서는
ref.watch(…) 같은 걸 직접 못 써.

ref.watch()는 Provider가 들고 있는 상태를 실시간으로 구독하는 거고,
그건 Riverpod이 제공하는 특별한 구조 안에서만 동작하니까
Consumer로 감싸줘야 된다.


예시로 직접 보자

final counterProvider = StateProvider<int>((ref) => 0);

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Consumer(
          builder: (context, ref, child) {
            final count = ref.watch(counterProvider);
            return Text('Count: $count');
          },
        ),
      ),
      floatingActionButton: Consumer(
        builder: (context, ref, child) {
          return FloatingActionButton(
            onPressed: () {
              ref.read(counterProvider.notifier).state++;
            },
            child: Icon(Icons.add),
          );
        },
      ),
    );
  }
}

이 코드에서 ref.watch()counterProvider의 상태를 구독하고,
그 값이 바뀔 때마다 builder를 다시 실행해.


ConsumerWidget이랑 뭐가 달라?

구분 Consumer ConsumerWidget
형태 위젯 안에 builder로 넣어서 사용 클래스 자체가 상태를 감시
용도 부분만 상태감시 하고 싶을 때 전체 위젯이 Provider에 의존할 때
코드 구조 더 유연하게 나눌 수 있음 간단하게 구현 가능

예를 들어 전체 화면이 Provider 상태를 참조한다면 ConsumerWidget이 편해.
근데 일부 위젯만 다시 그려주고 싶다면 Consumer로 분리하는 게 좋아.


요약하자면

  • Consumer는 Provider 상태를 구독해서 위젯을 다시 빌드해주는 도구
  • builder 안에서 ref.watch()를 사용
  • 꼭 필요한 곳만 Consumer로 감싸서 사용해야 성능에 좋음
  • ref.read()는 watch가 아니라서 위젯 빌드 안 됨 (단발성 이벤트용)