오늘은 Consumer에 대해 공부할 것이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class MyApp extends HookWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: ChangeNotifierProvider<MyString>(
create: (context) => MyString(), child: MyWidget())));
}
}
class MyString with ChangeNotifier {
String _myString = "";
String get myString => _myString;
changeMyString(value) {
_myString = value;
notifyListeners();
}
}
class MyWidget extends HookWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
final useFormKey = useMemoized(() => GlobalKey<FormState>());
var myString = Provider.of<MyString>(context);
print('my widget');
return Column(
children: [
Form(
key: useFormKey,
child: TextFormField(
onSaved: (String? value) {
myString.changeMyString(value);
},
),
),
ElevatedButton(
onPressed: () {
if (useFormKey.currentState != null)
{
useFormKey.currentState!.save();
print(myString.myString);
}
}, child: const Text("출력")),
AnotherWidget(),
],
);
}
}
class AnotherWidget extends HookWidget {
AnotherWidget({super.key});
@override
Widget build(BuildContext context) {
print('another widget');
return Text("AnotherWidget");
}
}
AnotherWidget은 MyWidget 안에서 실행되었는데, 문제는 Provider를 쓰지 않았음에도 계속해서 re-build가 됨을 확인할 수 있다. 이것은 매우 큰 낭비다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class MyWidget extends HookWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
print('my widget');
return Column(
children: [
Consumer<MyString>(
builder: (BuildContext context, value, Widget? child) {
return MyColumn();
},
),
AnotherWidget(),
],
);
}
}
class AnotherWidget extends HookWidget {
AnotherWidget({super.key});
@override
Widget build(BuildContext context) {
print('another widget');
return Text("AnotherWidget");
}
}
class MyColumn extends HookWidget {
MyColumn({super.key});
@override
Widget build(BuildContext context) {
final useFormKey = useMemoized(() => GlobalKey<FormState>());
var myString = Provider.of<MyString>(context);
return Column(children: [
Form(
key: useFormKey,
child: TextFormField(
onSaved: (String? value) {
myString.changeMyString(value);
},
),
),
ElevatedButton(
onPressed: () {
if (useFormKey.currentState != null) {
useFormKey.currentState!.save();
print(myString.myString);
}
},
child: const Text("출력")),
]);
}
}
Consumer는 위와 같이 사용한다. Provider와 마찬가지로 인자가 여러가지면 Consumer 뒤에 2~6까지의 수를 붙이고 가운데의 인자 수를 하나씩 늘리면 된다. 희한하게도 Consumer의 인자 수는 앞서 말했듯이 가운데, 그러니까 (context, value, child) 여기서 value가 바로 인자다.
Consumer를 사용하면 말 그대로 프로바이더 연결을 혼자 그 구간에서 독식해버린다. 따라서 MyColumn은 실행되지만 AnotherWidget이 re-build되지는 않는다.