728x90

플러터 위젯 상태(state)를 관리하는 기본 방법은 setState인데, 이는 state를 업데이트 하고 위젯을 다시 빌드하는 메소드이다. 

※ Class 내에서 사용하는 function 은 메소드로 통칭한다.

부모 자식 위젯간에는 유용하지만 위젯 Depth가 커지면, 즉 조부모 → 손자 간에는 데이터 전달이 쉽지 않다.

앱의 규모가 커지면 코드는 복잡해지고 효과적인 상태 관리가 필요하다는 것을 느끼게 된다.

 

https://pub.dev/packages/provider/install 에서 최신 버전을 확인하고 pubspec.yaml 파일에 추가한다.

dependencies:
  provider: ^6.0.3

import 'package:provider/provider.dart';

를 하면 기본 준비 완료이다.

 

기존 main 함수

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

 

변경 main 함수

void main() {
  runApp(
    MultiProvider(providers: [
      ChangeNotifierProvider(create: (c) => Counter()),
    ],
    child: const MyApp(),
    )
  );
}

 

상태관리 클래스를 추가한다.

provider/counter_provider.dart

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
 
class CounterProvider extends ChangeNotifier {
  int _count = 0;
 
  int get count => _count;
 
  void increment() {
    _count++;
    notifyListeners();
  }
 
  void decrement() {
    _count--;
    notifyListeners();
  }
}
 

 

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter/foundation.dart';
import 'counterview_home.dart';
import './provider/counter_provider.dart';
 
void main() {
  runApp(
    MultiProvider(providers: [
      ChangeNotifierProvider(create: (c) => CounterProvider()),
    ],
    child: const MyApp(),
    )
  );
}
 
class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);
 
  @override
  State<MyApp> createState() => _MyAppState();
}
 
class _MyAppState extends State<MyApp> {
 
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      // home: const DrawerMenu(title: 'Drawer Demo'),
      home: CounterView_Home(),
    );
  }
}

 

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import './provider/counter_provider.dart';
 
class CounterView_Home extends StatelessWidget {
  const CounterView_Home({Key? key}) : super(key: key);
 
  @override
  Widget build(BuildContext context) {
    CounterProvider counterProvider = Provider.of<CounterProvider>(context,listen: false);
    //print('CounterView rendering');
    return Scaffold(
      appBar: AppBar(
        title: const Text('Provider Counter Example'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: const <Widget>[
            Text('You have pushed the button this many times:'),
            Count(),
          ],
        ),
      ),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          IconButton(
            //onPressed: () => context.read<CounterProvider>().increment(),
            onPressed: () => counterProvider.increment(),
            icon: Icon(Icons.add),
          ),
          IconButton(
              //onPressed: () => context.read<CounterProvider>().decrement(),
              onPressed: () => counterProvider.decrement(),
              icon: Icon(Icons.remove)),
        ],
      ),
    );
  }
}
 
class Count extends StatelessWidget {
  const Count({Key? key}) : super(key: key);
 
  @override
  Widget build(BuildContext context) {
    return Text('${context.watch<CounterProvider>().count}',
        key: const Key('counterState'),
        style: Theme.of(context).textTheme.headline4);
  }
}

 

 

블로그 이미지

Link2Me

,