๊ด€๋ฆฌ ๋ฉ”๋‰ด

ruriruriya

[Flutter] ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ Provider ํŒจํ‚ค์ง€ ๋ณธ๋ฌธ

๐Ÿ“ฑFlutter/Flutter Framework

[Flutter] ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ Provider ํŒจํ‚ค์ง€

๋ฃจ๋ฆฌ์•ผใ…‘ 2025. 2. 25. 16:44
๋ฐ˜์‘ํ˜•

Provider๋Š” Flutter์—์„œ ๊ณต์‹์ ์œผ๋กœ ์ถ”์ฒœํ•˜๋Š” Flutter ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ค‘ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ํŒจํ‚ค์ง€์ด๋‹ค.

 

1. Provider๋ž€?

Provider๋Š” Flutter์˜ InheritedWidget์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋„๋ก ๋•๋Š” ํŒจํ‚ค์ง€๋กœ ์—ฌ๋Ÿฌ ์œ„์ ฏ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•˜๊ณ , ์ƒํƒœ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜์—ฌ UI๋ฅผ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋‹ค.

โœ” Provider๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์€ ์ 

  1. ๋ฆฌ์†Œ์Šค ํ• ๋‹น ๋ฐ ํ•ด์ œ ๊ด€๋ฆฌ๊ฐ€ ๊ฐ„๋”˜ํ•ด์ง
    → ๋ถˆํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ์„ ์ค„์ด๊ณ  ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Œ.
  2. Lazy-loading ์ง€์›
    → ํ•„์š”ํ•  ๋•Œ๊นŒ์ง€ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š์•„์„œ ์„ฑ๋Šฅ ์ตœ์ ํ™”๊ฐ€ ๊ฐ€๋Šฅํ•จ.
  3. ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ ๊ฐ์†Œ
    → ์ƒˆ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•  ๋•Œ๋งˆ๋‹ค ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ๊ฐ€ ์ค„์–ด๋“ฆ.
  4. Flutter DevTools์™€ ํ˜ธํ™˜
    → DevTools์—์„œ ์•ฑ ์ƒํƒœ๋ฅผ ์‹œ๊ฐ์ ์˜๋กœ ํ™•์ธ ๊ฐ€๋Šฅ.
  5. ๊ณตํ†ต๋œ ์†Œ๋น„ ๋ฐฉ๋ฒ• ์ œ๊ณต
    → Provider.of, Consumer, Selector ๊ฐ™์€ API๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Œ.
  6. ํ™•์žฅ์„ฑ ์ฆ๊ฐ€
    → ChangeNotifier ๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ๋ณต์žก์„ฑ์ด ์ฆ๊ฐ€ํ•˜๋Š” ๊ฑธ ๋ง‰์•„์คŒ.

 

2. Provider์˜ ์‚ฌ์šฉ๋ฒ•

 

2.1. ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•  ๋•Œ(create ์‚ฌ์šฉ)

Provider๋Š” ๋‹จ์ˆœํžˆ ๊ฐ’์„ ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ด€๋ฆฌํ•˜๊ณ , ํ•ด์ œํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

(๐Ÿšจ ์ฃผ์˜! create๊ฐ€ ์•„๋‹Œ .value๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ)

Provider(
  create: (_) => MyModel(), // ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
  child: MyApp(),
);

 

2.2. ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ์žฌ์‚ฌ์šฉํ•  ๋•Œ (value ์‚ฌ์šฉ)

์ด๋ฏธ ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด๋ฅผ Provider๋ฅผ ํ†ตํ•ด ์ „๋‹ฌํ•˜๋ ค๋ฉด .value๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

final myModel = MyModel();

ChangeNotifierProvider.value(
  value: myModel, // ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•  ๋•Œ๋Š” .value ์‚ฌ์šฉ!
  child: MyApp(),
);

 

3. Provider์—์„œ ๊ฐ’ ์ฝ๊ธฐ

3.1. context.watch<T>() → UI ์ž๋™ ์—…๋ฐ์ดํŠธ

  • ์ƒํƒœ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค UI๋ฅผ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธํ•จ.
  • build() ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.
Text(
  context.watch<String>(), // ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด UI ์ž๋™ ์—…๋ฐ์ดํŠธ
);

 

3.2. context.read<T>() → ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ (UI ๋ณ€๊ฒฝ ์—†์Œ)

  • ๋‹จ์ˆœํžˆ ๊ฐ’์„ ํ•œ ๋ฒˆ ๊ฐ€์ ธ์˜ค๊ณ , UI ์—…๋ฐ์ดํŠธ ์—†์ด ์‚ฌ์šฉํ•  ๋•Œ ์ ํ•ฉ.
  • build() ํ•จ์ˆ˜ ์™ธ๋ถ€์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.
ElevatedButton(
  onPressed: () {
    print(context.read<Counter>().count); // ์ƒํƒœ๋ฅผ ์ฝ๊ธฐ๋งŒ ํ•จ (UI ๋ณ€๊ฒฝ X)
  },
  child: Text("Print Count"),
);

 

3.3. context.select<T, R>(R cb(T value)) → ํŠน์ • ๊ฐ’๋งŒ ๊ฐ์ง€

  • ๊ฐ์ฒด์˜ ์ผ๋ถ€ ๊ฐ’๋งŒ ๊ฐ์ง€ํ•˜๊ณ  UI๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ.
final name = context.select((Person p) => p.name); // name์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งŒ UI ์—…๋ฐ์ดํŠธ
return Text(name);

 

4. MultiProvider ์‚ฌ์šฉ๋ฒ•

Provider๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ์ค‘์ฒฉํ•ด์„œ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ MultiProvider๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋” ๊น”๋”ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

MultiProvider(
  providers: [
    Provider<Something>(create: (_) => Something()),
    Provider<SomethingElse>(create: (_) => SomethingElse()),
  ],
  child: MyApp(),
);

 

5. ProxyProvider ์‚ฌ์šฉ๋ฒ•

ProxyProvider๋Š” ๋‹ค๋ฅธ Provider์˜ ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

๐Ÿ“Œ ์žฅ์ 

  • Counter๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค Translations ๊ฐ์ฒด๋„ ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ๋จ.
  • ์ƒํƒœ ๊ฐ„์˜ ์˜์กด์„ฑ์„ ์„ค์ •ํ•  ๋•Œ ์œ ์šฉํ•จ.
Widget build(BuildContext context) {
  return MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (_) => Counter()),
      ProxyProvider<Counter, Translations>(
        update: (_, counter, __) => Translations(counter.count),
      ),
    ],
    child: Foo(),
  );
}

class Translations {
  final int count;
  Translations(this.count);

  String get title => 'You clicked $count times';
}
๋ฐ˜์‘ํ˜•