min_chan님의 블로그

[pub.dev] - provider 본문

pub.dev

[pub.dev] - provider

min_chan 2025. 2. 24. 10:45

 

Flutter에서 상태 관리는 필수적인 요소입니다.

여러 상태 관리 방법 중에서도 Provider는 가장 널리 사용되는 패키지 중 하나로 이번 글에서는 Provider의 개념, 사용법, 그리고 예제 코드를 통해 어떻게 활용할 수 있는지 알아보겠습니다.


Provider란?

  • Provider는 Flutter에서 상태 관리(State Management)를 효율적으로 할 수 있도록 도와주는 패키지입니다.

Provider의 장점

  • 자원 할당 및 해제의 간소화: 필요할 때만 자원을 할당하고 해제하여 효율성을 높임
  • 지연 로딩(lazy-loading) 지원: 필요한 순간까지 데이터를 로드하지 않음
  • 반복적인 보일러플레이트 코드 감소: 새로운 클래스를 매번 만들 필요 없이 간결한 코드 유지 가능
  • 개발 도구(DevTool) 친화적: Provider를 사용하면 앱의 상태를 Flutter 개발 도구에서 쉽게 확인 가능
  • 일관된 상태 소비 방식 제공: Provider.of, Consumer, Selector 등을 통해 상태를 효과적으로 가져올 수 있음
  • 확장성이 뛰어남: ChangeNotifier와 같은 O(N) 복잡도를 가지는 리스닝 메커니즘을 보다 효율적으로 관리 가능

setState VS Provider

  setState Provider
기본 개념 위젯 내부에서 상태 변경 및 UI 업데이트 수행 전역적으로 상태를 관리하고 UI에 반영
사용 방법 setState(() { 상태 변경 });을 호출하여
해당 위젯만 다시 빌드
notifyListeners()를 호출하면 Provider를 구독하는 모든 위젯이 갱신
리빌드 범위 setState를 호출한 위젯만 리빌드 Provider를 사용하는 여러 위젯에서 상태 공유 가능
상태 저장 위치 StatefulWidget 내부에서만 상태 유지 가능 전역적으로 유지 가능 (MultiProvider를 통해 여러 곳에서 접근 가능)
복잡한 상태 관리 단순한 상태 변경에는 적합하지만
여러 위젯에서 공유하려면 불편
여러 위젯에서 동일한 상태를 쉽게 공유 가능

Provider 사용법

 

1. 터미널에서 flutter pub add 명령어를 실행해 패키지를 설치

 

2. 상태 클래스 작성

Provider를 사용하려면 변경 가능한 상태를 담을 클래스를 만든다. ChangeNotifier를 상속받아 구현

import 'package:flutter/material.dart';

class Counter with ChangeNotifier {
  int _count = 0;
  
  int get count => _count;
  
  void increment() {
    _count++;
    // 상태 변경 시 UI에 알림
    notifyListeners(); 
  }
}

 

3. Provider 등록

main.dart 파일에서 최상위 위젯에 Provider를 등록

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'counter.dart';

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => Counter(),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CounterScreen(),
    );
  }
}

 

4. Provider 사용

Provider에 등록한 상태를 사용하려면 Consumer 위젯이나 Provider.of 메소드를 활용

class CounterScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Provider.of를 통해 상태 접근 (listen:true 기본값)
    final counter = Provider.of<Counter>(context);
    
    return Scaffold(
      appBar: AppBar(title: Text('Provider 예제')),
      body: Center(
        child: Text('카운트: ${counter.count}', style: TextStyle(fontSize: 30)),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => counter.increment(),
        child: Icon(Icons.add),
      ),
    );
  }
}

 

또는 Consumer 위젯을 사용하면 리빌드할 부분을 더 세밀하게 제어

class CounterScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Provider 예제')),
      body: Center(
        child: Consumer<Counter>(
          builder: (context, counter, child) {
            return Text('카운트: ${counter.count}', style: TextStyle(fontSize: 30));
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => Provider.of<Counter>(context, listen: false).increment(),
        child: Icon(Icons.add),
      ),
    );
  }
}

'pub.dev' 카테고리의 다른 글

[pub.dev] - dio  (0) 2025.03.14
[pub.dev] - http  (0) 2025.03.13
[pub.dev] - flutter_secure_storage  (0) 2025.03.05
[pub.dev] - flutter_dotenv  (0) 2025.02.27
[pub.dev] - pub.dev  (0) 2025.02.19