Menu
CoddyTech

Provider: Consumer

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

여기서는 공급자가 MyApp 자체의 build 안에서 만들어지고, 같은 build에서 바로 아래에 있는 램프를 요청합니다. 앱에 오류가 표시됩니다. context는 공급자 위에 있는 MyApp에 속하며, 위젯은 자신보다 위에 있는 공급자만 찾을 수 있습니다.

Consumer를 사용하면 이 문제를 해결할 수 있습니다. 위젯이므로 공급자 아래에 위치하며, builder에는 새로운 context와 모델 자체가 전달됩니다.

Consumer<Lamp>(
  builder: (context, lamp, child) {
    return Text(lamp.isOn ? 'On' : 'Off');
  },
)

램프가 notifyListeners()를 호출할 때마다, 램프를 감시하는 위젯처럼 빌더가 다시 실행됩니다. 빌더 안에서는 모델의 메서드를 lamp에서 바로 호출할 수 있습니다. 예를 들면 onPressed: () => lamp.toggle()입니다.

Consumer는 감싸고 있는 부분만 다시 빌드하므로, 변경되는 부분을 감싸면 화면의 나머지 부분은 그대로 유지됩니다. 대부분의 앱에서는 별도의 위젯에서 context.watch를 사용하고, 공급자와 같은 build 안에 있을 때는 Consumer를 사용합니다.

challenge icon

챌린지

중급

앱을 열면 오류가 발생합니다. 전등의 구성 요소를 Consumer 안에 넣으세요:

  • Column을 Consumer<Lamp>로 감싸고, 빌더에서 Column을 반환하세요.
  • 그 안에서 아이콘, 텍스트, 버튼에 빌더의 lamp를 사용하세요.

직접 해보기

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

class Lamp extends ChangeNotifier {
  bool _isOn = false;

  bool get isOn => _isOn;

  void toggle() {
    _isOn = !_isOn;
    notifyListeners();
  }
}

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

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

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Lamp(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
          appBar: AppBar(title: const Text('Lamp')),
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(
                  context.watch<Lamp>().isOn ? Icons.lightbulb : Icons.lightbulb_outline,
                  size: 96,
                  color: context.watch<Lamp>().isOn ? Colors.amber : Colors.grey,
                ),
                Text(context.watch<Lamp>().isOn ? 'The lamp is on' : 'The lamp is off'),
                const SizedBox(height: 16),
                ElevatedButton(
                  onPressed: () => context.read<Lamp>().toggle(),
                  child: const Text('Switch'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
quiz icon실력 점검

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

상태 관리의 모든 레슨

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