Menu
CoddyTech

Provider: 모델 공유하기

Coddy Flutter 여정의 상태 관리 섹션에 포함된 레슨. 27개 중 9번째.

상태 끌어올리기는 위젯들이 서로 가까이 있을 때 효과적입니다. 앱 전체, 두 개의 화면, 상단 바, 목록 깊숙한 곳에서 값이 필요하다면 그 사이에 있는 모든 위젯을 거쳐 값을 전달해야 합니다. Provider는 그런 과정을 생략합니다. 패키지란 가져와서 사용하는 코드 묶음입니다. import 'package:provider/provider.dart';처럼 가져옵니다.

세 부분으로 이루어져 있습니다. 첫째, 모델입니다. 데이터를 보유하고 extends ChangeNotifier를 사용하는 클래스입니다. 메서드는 데이터를 변경한 다음 notifyListeners()를 호출합니다.

class CupCounter extends ChangeNotifier {
  int _cups = 0;
  int get cups => _cups;

  void addCup() {
    _cups++;
    notifyListeners();
  }
}

둘째, 트리의 상위에 있는 ChangeNotifierProvider가 모델을 한 번 생성하고 그 아래의 모든 위젯에 전달합니다.

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

셋째, 아래에 있는 위젯은 모델을 요청합니다. 표시할 때는 context.watch<CupCounter>()를, 메서드를 호출할 때는 context.read<CupCounter>()를 사용합니다. 아래의 제목과 버튼은 동일한 카운터를 가져오며, 둘 다 어떤 값도 전달받지 않습니다.

challenge icon

챌린지

중급

앱을 열면 오류가 표시됩니다. 제목에서 CupCounter를 요청하지만 그 위에서 이를 제공하는 것이 없기 때문입니다.

  • main에서 MyApp을 CupCounter를 생성하는 ChangeNotifierProvider로 감싸세요.

직접 해보기

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

class CupCounter extends ChangeNotifier {
  int _cups = 0;

  int get cups => _cups;

  void addCup() {
    _cups++;
    notifyListeners();
  }
}

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const CupsTitle()),
      body: const Center(child: AddCupButton()),
    );
  }
}

class CupsTitle extends StatelessWidget {
  const CupsTitle({super.key});

  @override
  Widget build(BuildContext context) {
    final counter = context.watch<CupCounter>();
    return Text('Cups: ${counter.cups}');
  }
}

class AddCupButton extends StatelessWidget {
  const AddCupButton({super.key});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {
        context.read<CupCounter>().addCup();
      },
      child: const Text('Another cup'),
    );
  }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

상태 관리의 모든 레슨

직접 연습해 보세요: 온라인 Flutter 컴파일러