1. ๋ค์ด๊ฐ๊ธฐ์ ์์
Provider๋ InheritedWidget์ ๋ณด๋ค ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ๋์์ฃผ๋ ์ํ๊ด๋ฆฌ ํจํค์ง์ ๋๋ค.
1. ์์ฑํด์ผ ํ๋ ์ฝ๋ ๊ฐ์
2. ์ํ๋ ์์ ฏ๋ง ์ ํ์ ์ผ๋ก ๊ฐฑ์ ๊ฐ๋ฅ
3. Lazy loading ์ง์
4. ์ํ๋ฅผ ๋ณ๋ ํด๋์ค๋ก ๋ถ๋ฆฌํ๋ฏ๋ก StatefulWidget ๋ณด๋ค ์ ์ง ๊ด๋ฆฌ ์ฉ์ด
- ๋จ์
1. Provider๊ฐ ๋ถ๋ชจ ์์ ฏ์ผ๋ก ๋ฑ๋ก๋์ด ์์ง ์์ ๊ฒฝ์ฐ, ์์ ์์ ฏ์์ ์ ๊ทผ์ ๋ฐํ์ ์๋ฌ๊ฐ ๋ฐ์
2. ์์ ฏ ํธ๋ฆฌ์์ ๋ฑ๋ก์ ์์กด์ฑ ์์ ์ค์
2. Provider ์ฌ์ฉํด๋ณด๊ธฐ
2-1. Provider ์ฌ์ฉ๋ฒ ๊ฐ๋ต ์ค๋ช
Provider๋ ChangeNotifier๋ฅผ ์์๋ฐ์์, ๋ณ๊ฒฝ์ฌํญ์ด ์๋ ๊ฒฝ์ฐ์ notifyListener()๋ฅผ ํธ์ถํ์ฌ ์์ ์์ ฏ๋ค์ ๊ฐฑ์ ํฉ๋๋ค.
๐ก DartPad์์ Provider๋ฅผ ์ด์ฉํ ์ํ ๊ด๋ฆฌ ์์
https://dartpad.dev/?id=d7b22cc9ba4dfa4bd71b2583a94e31b4
ChangeNotifierProvider(
create: (context) => FirstProvider(),
child: const MaterialApp(
home: HomeScreen(),
),
);
InheritedWidget์ ๋ถ๋ชจ ์์ ฏ์ผ๋ก ์ถ๊ฐํ๋ ๊ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก, Provider๋ ์์ ฏ ํธ๋ฆฌ์ ๋ค์๊ณผ ๊ฐ์ด ์ถ๊ฐํด์ผ ์์ ์์ ฏ๋ค์ด ์ ๊ทผ์ ํ ์ ์๊ฒ ๋์์ค๋๋ค.
Widget build(BuildContext context) {
print('reBuild');
FirstProvider provider = context.watch<FirstProvider>();
return Scaffold(
body: Center(
child: Text('${provider.counter}'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => provider.increment(),
child: const Icon(Icons.plus_one),
),
);
}
์์์์ ฏ์์๋ context.watch()๋ก Provider์ ์ ๊ทผํ ์ ์์ด์ ๋ง์ฝ listenํ๊ณ ์๋ ๊ฐ๋ค์ ๋ณ๋์ฌํญ์ด ์๊ธด๋ค๋ฉด
notifyListener()๋ฅผ ํธ์ถํ๊ณ ์๋กญ๊ฒ Build()ํจ์๊ฐ ํ๋ฉด์ ์๋กญ๊ฒ ๊ฐฑ์ ํ๊ฒ ๋ฉ๋๋ค.
๐ก context.watch()๋ Providerํจํค์ง์์ extension์ผ๋ก Buildcontext๋ฅผ ํ์ฅํ์ฌ ๊ตฌํํ ํจ์ ์ ๋๋ค.
2-2. ๊ฐ ์ฝ๊ธฐ
๊ฐ์ ์ฝ๋ ๋ฐฉ๋ฒ์ผ๋ก๋ ๊ณต์๋ฌธ์์์๋ 3๊ฐ์ง ๋ฐฉ๋ฒ์ ์ค๋ช ํ๊ณ ์์ต๋๋ค.
1. context.watch<T>() : ์์ ฏ์ด T์ ๋ณํ๋ฅผ ๊ฐ์งํ ์ ์๋๋ก ํฉ๋๋ค.
== Provider.of<T>(context, listen : true)
2. context.read<T>() : T๋ฅผ ๋ณํ ๊ฐ์ง ์์ด return ํฉ๋๋ค.
== Provider.of(context, listen : false)
3. context.select<T, R> : T์ ์ผ๋ถ ์์ ์์ญ์ ๋ํด์๋ง ์์ ฏ์ด ๋ณํ๋ฅผ ๊ฐ์งํ ์ ์๋๋ก ํฉ๋๋ค.
๊ฐ๋จํ๊ฒ ์ํ๊ฐ ๋ณํ๋์ ์ฌ๋น๋๋ฅผ ํ๊ณ ์ถ์๋๋ watch๋ฅผ ์๋๊ฒฝ์ฐ๋ read๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
์ด ๋ง์ ์ฆ, read๋ ๊ฐ์ด ๋ณ๊ฒฝ๋์์ ๋ ์์ ฏ์ ์ฌ๋น๋ ํ์ง ์์ผ๋ฏ๋ก stf widget์์๋ ์ฌ์ฉํ ์๊ฐ ์๋ค๋ ์๋ฏธ๊ฐ ๋ฉ๋๋ค.
2-3. Provider์ ์ ํ์ ์์กด ๋ฐ ๋ค์ค Provider
context.watch<Model>()
์ ์ฝ๋์์ ๋ง์ฝ Model์ด๋ผ๋ Provider๊ฐ ์กด์ฌํ์ง ์๋๋ค๋ฉด
ProviderNotFoundException ์์ธ๊ฐ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
๊ทธ๋์ ๋งค์นญ๋๋ provider๋ฅผ ์ฐพ์ง ๋ชปํ์ ๊ฒฝ์ฐ์๋ null๊ฐ์ ๋ฐํํ๋๋ก ํ๊ธฐ ์ํด์๋
context.watch<Model?>()
์ ์ฒ๋ผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
๋ค๋ง provider๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ๋ฅผ ์ง์ํ๋ ์ผ์ด์ค๊ฐ ๋ญ๊ฐ ์๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค...
(provider๊ฐ ์กด์ฌํ๋๊น read/watch๋ฅผ ์ฌ์ฉํ๋๊ฑด๋ฐ... null๊ฐ์ด ์์๋ฆฌ๊ฐ..์๋?)
์์ผ๋๊น ์ง์ํ๊ฒ ์ฃ ..?
๋๋ฒ์งธ๋ก๋ MultiProvider์ ๋๋ค.
์ง๊ธ๊น์ง ๋ฐฐ์ด ๋ด์ฉ์ผ๋ก๋ ๋ง์ฝ ๋ฑ๋กํ๋ ค๋ Provider๊ฐ 2๊ฐ ์ด์์ผ ๊ฒฝ์ฐ๋
Provider<Something>(
create: (_) => Something(),
child: Provider<SomethingElse>(
create: (_) => SomethingElse(),
child: Provider<AnotherThing>(
create: (_) => AnotherThing(),
child: someWidget,
),
),
),
์ด๋ ๊ฒ ์์ฑํด์ผ ํ ํ ๋ฐ ๊ฐ๋ ์ฑ์ด ๋งค์ฐ ์ข์ง ์์ต๋๋ค.
์ด๋ฅผ ์๋์ ๊ฐ์ด ์์ฑํ ์ ์์ต๋๋ค.
MultiProvider(
providers: [
Provider<Something>(create: (_) => Something()),
Provider<SomethingElse>(create: (_) => SomethingElse()),
Provider<AnotherThing>(create: (_) => AnotherThing()),
],
child: someWidget,
)
์ ๋ ์ฝ๋๋ ์์ ํ ๋์ผํ๊ฒ ์๋ํ๊ณ , MultiProvider๋ ๋จ์ํ ์ฝ๋์ ์ธ๊ด์ ๋ฐ๊ฟ์ค ๋ฟ์ ๋๋ค.
2-4. ProxyProvider๋?
ProxyProvider๋ 3.0.0 ๋ฒ์ ๋ถํฐ ์๋กญ๊ฒ ์ถ๊ฐ๋ ๊ธฐ๋ฅ์ ๋๋ค.
๋ค๋ฅธ provider๋ค์ ์ฌ๋ฌ ๊ฐ์ ํ๋์ ๊ฐ์ฒด๋ก ๋ฌถ์ด Provider๋ก ์ ๋ฌํ๋ provider ์ ๋๋ค.
๊ทธ๋ฌ๋ฉด ํด๋น ์ ๊ท ๊ฐ์ฒด๋ ์ฐ๋ฆฌ๊ฐ ์์กดํ๋ provider ์ค ํ๋๊ฐ ์ ๋ฐ์ดํธ ๋ ๋๋ง๋ค ์ ๋ฐ์ดํธ ๋ฉ๋๋ค.
๊ณต์๋ฌธ์๋ฅผ ์ฝ์ผ๋ฉด์ ์ด๊ฑธ ๋๋์ฒด ์ธ์ ์ฐ๋๊ฑฐ์ง..? ๋ผ๋ ์๊ฐ์ด ๋ค์์ต๋๋ค.
์๋ ์์์ ํจ๊ป ์ด๋จ๋ ์ฌ์ฉํ๋ฉด ์ข์์ง ๋ณด๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
int count;
Provider(
create: (_) => MyModel(count),
child: ...
)
์์ ๊ฐ์ด Provider์ ๋ณ๊ฒฝ๋ ์ ์๋ ๋ณ์๋ก ๊ฐ์ฒด๋ฅผ ๋ง๋ ๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค.
์ด๋ ๊ฒ ์์ฑ์ ํ๋ค๊ณ ํ๋ค๋ฉด, ์์ฑ๋ ๊ฐ์ฒด๋ ๊ฐ์ด ๋ณํํด๋ ์ ๋ฐ์ดํธ๊ฐ ๋์ง ์์ ๊ฒ ์ ๋๋ค.
๋ํ, ์ค์ ๋ก ๊ณต์๋ฌธ์์๋ ์ด๋ ๊ฒ ์ฌ์ฉํ์ง ๋ง๋ผ๊ณ ๊ถ์ฅํฉ๋๋ค.
int count;
ProxyProvider0(
update: (_, __) => MyModel(count),
child: ...
)
์ด๋ ๊ฒ ProxyProvider๋ฅผ ํตํด์ ์๊ฐ์ ๋ฐ๋ผ ๋ณ๊ฒฝ๋ ์ ์๋ ๋ณ์๋ก๋ฅผ ๊ฐ์ฒด์ ์ ๋ฌํ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์ ProxyProvider์ ์๋ ์ซ์๋ ProxyProvider๊ฐ ์์กดํ๋ ๋ค๋ฅธ ๊ณต๊ธ์์ ์ ์ ๋๋ค.
https://dartpad.dev/?id=71e1f23bf7076de716bcb30811a7eb8d
์์ธํ ๋ด์ฉ์ ์ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์
1์ด๋ง๋ค ๋ณ๊ฒฝ๋๋ ํ์ฌ ์๊ฐ์ ๊ฐ์ ๋ณ์๋ฅผ ProxyProvider์ ์ ๋ฌํ์ฌ ๊ฐ์ฒด๋ฅผ ๋ง๋ ์์ ์ ๋๋ค.
2-5. Consumer
consumer๋ watch์ ๋์ผํ๋, ํน์ ์์ ฏ๋ง ๊ฐฑ์ ํ ์ ์์ต๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก๋ ์ํ๊ฐ ๋ณํ๊ฒ ๋๋ฉด Build()ํจ์๋ถํฐ ์ฌ๋น๋๊ฐ ์์๋๋๋ฐ
Cosumer๋ก ์์ ฏ์ ๊ฐ์ธ๋ฉด ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ๊ทธ ์์์๋ง ์ํ๊ฐ ๋ณ๊ฒฝ๋๊ฒ ๋ฉ๋๋ค.
https://dartpad.dev/?id=c9d05cc219059a84e3d832c49c84a87e
'MyApp build() ์คํ ๋จ' ์ด๋ผ๋ ํ ์คํธ๋ ํ๋ฒ๋ง ์ถ๋ ฅ์ด ๋๊ณ
counter์ ๊ฐ์ด ์ฆ๊ฐํด๋ Cosumer ์์์๋ง ์ํ๊ฐ ๋ณํ๊ธฐ ๋๋ฌธ์
'MyApp build() ์คํ ๋จ'์ ๋์ด์ ์คํ๋์ง ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
2-6. Selector
select์ ๋์ผํ๋, ํน์ ์์ ฏ๋ง ๊ฐฑ์ ํฉ๋๋ค.
https://dartpad.dev/?id=070c0a54bec23b5bc158791db90ba0c2
3. Provider ์ ๊ณต์
๋ง์ฝ ๋ณ๊ฒฝ์ฌํญ์ ์๋ฆด ํ์๊ฐ ์๋ ํด๋์ค๋
ChangeNotifierProvider๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
ํ์ง๋ง ๋ณ๊ฒฝ์ฌํญ์ ์๋ฆด ํ์๊ฐ ์๋ค๋ฉด Provider๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.