[Flutter] Provider

mi-fasol·2023년 1월 25일
0

Flutter

목록 보기
2/7

해당 게시물은 과거에 작성한 블로그 내용을 옮겨 온 것으로, 가독성이 떨어지고 내용이 부정확할 수 있습니다.

Provider의 개념

  • 위젯의 State를 표시하려면 불필요한 위젯들이 ReBuild되는 문제가 발생
    • state: 위젯이 빌드되는 동시에 읽을 수 있으며 위젯의 생명 주기 사이에 변경 가능한 정보
    • 어플과 사용자 간의 상호작용으로 인하여 변하는 데이터들이 state에 해당
  • 해당 문제를 해결하기 위한 게 Provider
  • 동일한 데이터를 다른 위젯에게 공유할 때 Provider를 사용하여 전달
  • Provider를 사용하면 위젯 트리와 관계없이 state를 저장할 수 있는 클래스 생성
    • 해당 state를 공유하는 공통 부모 위젯이 Provider를 제공
    • state를 사용할 때는 Provider의 데이터를 가져와서 사용
  • 결론적으로 Provider는 state를 관리하기 위한 개념
  • Provider
    • 생성 파트: 사용할 데이터의 타입과 그 데이터에 대한 Provider를 생성
    • 소비 파트: Provider를 사용하여 데이터를 불러오고 수정

생성 예제

  • 생성할 프로그램: 숫자를 1씩 증가시키는 프로그램
  • count_provider.dart
// Counter Class 정의 
import 'package:flutter/material.dart';

class CountProvider extends ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increase() {   // 숫자를 증가시키는 함수
    ++_count;
    notifyListeners();  // 데이터가 갱신되었음을 알림
  }

  void decrease() {   // 숫자를 감소시키는 함수
    --_count;
    notifyListeners();  // 선언하지 않을 시 다른 위젯에서 변경된 걸 모름
  }
}
  • main.dart
// CountProvider 구독
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'provider/count_provider.dart';
import 'screen/home.dart';

void main() {
  runApp(App());
}

class App extends StatelessWidget {
  const App({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: ChangeNotifierProvider(   // CountProvidier를 구독
        create: (_) => CountProvider(), // CountProvider는 count_provider.dart에 선언
        child: Home(),  // Home 위젯에서 해당 Provider 사용 가능
      ),
    );
  }
}
  • home.dart
// CountProvider를 사용하기 위한 home 생성

import 'package:flutter/material.dart';
import 'package:flutter_temp/provider/count_provider.dart';
import 'package:provider/provider.dart';

class Home extends StatelessWidget {
  Home({Key? key}) : super(key: key);

  late CountProvider _countProvider;

  
  Widget build(BuildContext context) {
    // Provider.of -> CountProvider를 호출하고 직접 접근, 상태를 받아와 업데이트 가능
    // listen:false -> Home에서는 상태 변경만 하고 위젯을 ReBuild 할 필요가 없음
    _countProvider = Provider.of<CountProvider>(context, listen: false);

    return Scaffold(
      appBar: AppBar(
        title: Text('Provider example'),
      ),
      body: CountHome(),  // 아래에 선언되어 있음
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          IconButton(
            onPressed: () => _countProvider.increase(),
            icon: Icon(Icons.add),    // 아이콘 클릭 시 add()
          ),
          IconButton(
            onPressed: () => _countProvider.decrease(),
            icon: Icon(Icons.remove),   // 아이콘 클릭 시 remove()
          ),
        ],
      ),
    );
  }
}

class CountHome extends StatelessWidget {
  const CountHome({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return Center(
      // Consumer로 Provider에 접근한 후 데이터 받아옴
      child: Consumer<CountProvider>(   // Consumer -> 상태가 변경될 때마다 Build
        builder: (context, countProvider, child) => Text(
          Provider.of<CountProvider>(context).count.toString(), // count를 화면에 출력
          style: TextStyle(fontSize: 60),
        ),
      ),
    );
  }
}
profile
정위블

0개의 댓글