Provider.of<T>(context)

샤워실의 바보·2024년 2월 21일
0

Provider Flutter

목록 보기
1/3
post-thumbnail

이 Flutter 예제 코드는 provider 패키지를 사용하여 상태 관리를 구현합니다. provider는 Flutter에서 상태 관리를 위한 간결하고 효율적인 방법을 제공하는 인기 있는 라이브러리입니다. 아래에서 코드를 섹션별로 나누어 설명하고, 각 부분에 주석을 추가하겠습니다. 또한 provider의 핵심 개념도 함께 설명하겠습니다.

BreedAndAgeAge 클래스

  • 이 StatelessWidget들은 각각 Dog 객체의 품종과 나이를 표시합니다. Provider.of<T>(context) 메서드를 사용하여 Dog 객체에 접근합니다.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import 'models/dog.dart'; // Dog 모델 클래스를 정의한 파일을 임포트합니다.

void main() {
  runApp(const MyApp()); // 애플리케이션의 시작점입니다.
}

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

  
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Dog>(
      create: (context) => Dog(name: 'dog04', breed: 'breed04'), // Dog 객체를 생성하고 초기화합니다.
      child: MaterialApp(
        title: 'Provider 04',
        debugShowCheckedModeBanner: false, // 디버그 배너를 비활성화합니다.
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const MyHomePage(), // 앱의 홈 화면을 설정합니다.
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Provider 04'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          mainAxisSize: MainAxisSize.min,
          children: [
            Text(
              '- name: ${Provider.of<Dog>(context).name}', // Provider를 사용하여 Dog 객체의 name 속성에 접근합니다.
              style: TextStyle(fontSize: 20.0),
            ),
            SizedBox(height: 10.0),
            BreedAndAge(), // Dog의 품종과 나이를 표시하는 위젯을 포함합니다.
          ],
        ),
      ),
    );
  }
}

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

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(
          '- breed: ${Provider.of<Dog>(context).breed}', // Dog 객체의 breed 속성에 접근합니다.
          style: TextStyle(fontSize: 20.0),
        ),
        SizedBox(height: 10.0),
        Age(), // Dog의 나이를 표시하는 위젯을 포함합니다.
      ],
    );
  }
}

class Age extends StatelessWidget {
  const Age({
    Key? key,
  }) : super(key:

 key);

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(
          '- age: ${Provider.of<Dog>(context).age}', // Dog 객체의 age 속성에 접근합니다.
          style: TextStyle(fontSize: 20.0),
        ),
        SizedBox(height: 20.0),
        ElevatedButton(
          onPressed: () => Provider.of<Dog>(context, listen: false).grow(), // "Grow" 버튼이 클릭되면 Dog 객체의 grow 메서드를 호출합니다.
          child: Text(
            'Grow',
            style: TextStyle(fontSize: 20.0),
          ),
        ),
      ],
    );
  }
}

provider 패키지의 핵심 개념

  • Provider 패턴: 상태 관리를 위한 효율적인 패턴으로, 데이터를 생성하고 필요한 곳에 데이터를 제공합니다.
  • ChangeNotifier: Flutter에서 상태 변경을 알리는 데 사용되는 클래스입니다. notifyListeners() 메서드를 호출하면 이를 듣고 있는 위젯들이 다시 빌드됩니다.
  • ChangeNotifierProvider: ChangeNotifier를 상속받는 클래스의 인스턴스를 생성하고, 이를 트리 전체에 걸쳐 제공합니다. 위젯이 해당 데이터에 의존할 때마다 자동으로 리스너를 추가하고, 위젯이 사라지면 리스너를 제거합니다.
  • Provider.of<T>(context): 주어진 타입 T의 가장 가까운 인스턴스를 찾아 반환합니다. listen: false를 설정하면 데이터 변경시 위젯을 다시 빌드하지 않습니다.

Provider.of<T>(context) 메서드는 provider 패키지를 사용하여 Flutter에서 상태 관리를 할 때 중요한 역할을 합니다. 이 메서드는 BuildContext를 기반으로, 주어진 타입 T의 가장 가까운 인스턴스를 찾아 반환합니다. 여기서 타입 TChangeNotifierProvider에 의해 제공되는 데이터 모델의 타입입니다.

listen: false의 사용 이유

Provider.of<T>(context, listen: false)를 호출할 때 listen 매개변수를 false로 설정하는 것은 매우 특정한 사용 사례에 적용됩니다. 기본적으로, listentrue로 설정되어 있으며, 이는 Provider가 관리하는 데이터가 변경될 때마다 그 데이터를 사용하는 위젯이 자동으로 다시 빌드되어야 함을 의미합니다. 이는 상태의 변화를 UI에 실시간으로 반영해야 할 때 유용합니다.

그러나, 모든 상황에서 위젯이 데이터 변경에 반응하여 다시 빌드되는 것이 필요하지 않을 수 있습니다. 예를 들어, 단순히 데이터를 읽기만 하고, 데이터 변경 시 위젯을 다시 빌드할 필요가 없는 경우가 그러합니다. 이런 경우에 listen: false를 사용합니다. listen: false를 설정하면, 데이터 모델의 변경 사항이 있을 때 위젯이 다시 빌드되는 것을 방지할 수 있습니다. 이는 특히 사용자 입력이나 버튼 클릭 같은 이벤트를 처리할 때 유용하며, 이때 데이터를 변경하고 싶지만 변경에 따른 즉각적인 UI 갱신이 필요 없을 때 적합합니다.

InheritedWidget과의 연관성

provider 패키지는 내부적으로 Flutter의 InheritedWidget을 사용하여 작동합니다. InheritedWidget은 위젯 트리에서 데이터를 효율적으로 전달하고, 위젯 트리의 어느 지점에서든지 그 데이터에 접근할 수 있게 해주는 Flutter의 기본 메커니즘입니다. Provider.of<T>(context)는 이 InheritedWidget을 탐색하여 필요한 데이터 타입의 인스턴스를 찾습니다.

updateShouldNotifyInheritedWidget에서 오버라이드할 수 있는 메서드로, 데이터 변경 시 자식 위젯에게 알릴지 여부를 결정합니다. Providerlisten 매개변수와 유사하게, 이 메서드는 데이터 변화에 따른 위젯 트리의 특정 부분의 다시 빌드 여부를 제어하는 데 사용됩니다. listen: false를 설정하는 것은 updateShouldNotify에 의해 발생할 수 있는 재빌드를 명시적으로 무시하겠다는 의도를 가진 것으로 볼 수 있습니다.

요약하자면, listen: false를 사용하는 것은 성능 최적화 전략의 일부로 볼 수 있으며, 불필요한 위젯 빌드를 방지하여 앱의 성능을 향상시킬 수 있습니다. 그러나 데이터의 변경을 UI에 반영해야 하는 경우에는 listen: true를 유지해야 하며, 이는 기본 설정입니다.

profile
공부하는 개발자

0개의 댓글