Search

[Flutter] 자식 위젯에서 부모 위젯 state 참조하기: findAncestorStateOfType

subtitle
How to Update State of Parent Widget?
Created
2021/02/25 11:59
tags
flutter
tip
image source: flutter.ko-dev

부모 위젯의 state를 참조, 변경하는 법

자기 자신의 state를 업데이트하려면 setState를 쓰면 된다. 하지만 자식이 부모 위젯의 state를 참조 또는 변경하려면 어떻게 해야할까?
스택오버플로우에 질문이 올라왔고 질문자와 55명의 up vote를 받은 답변은 이러했다.
옛날 방법: _MyHomePageState의 글로벌 인스턴스를 생성해서 자식 Stateful Widget에서 _myHomePageState.setState로 사용해라.
새로운 방법: 글로벌 인스턴스로 생성할 필요 없이 부모 인스턴스를 자식 위젯에 전달해라.
옛날 방법은 글로벌 인스턴스를 생성한다는 점, 새로운 방법은 인스턴스 하나를 통째로 넘긴다는 점에서 둘 다 별로 좋아보이지 않는다. 또한, 바로 위의 부모가 아니라 더 상위 부모의 state를 변경하려면 부모 인스턴스를 계속해서 자식에게 전달(drilling)해야하는 수고스러움이 있다.

findAncestorStateOfType

Returns the State object of the nearest ancestor StatefulWidget widget that is an instance of the given type T (주어진 타입을 가진, 가장 가까운 부모 StatefulWidget의 State 객체를 반환한다.)
부모 위젯의 state를 참조할 수 있도록 하는 flutter api이다. 이게 가장 정도(正道)인 것 같다.
부모 위젯은 사실상 건드릴 게 없고, 자식 위젯만 수정하면 된다. 이렇게 하면 바로 위의 부모 말고도 더 위의 StatefulWidget 부모의 state도 수정할 수 있다.
class Parent extends StatefulWidget { ParentState createState() => ParentState(); } class ParentState extends State<Parent> { int page = 1; Widget build(BuildContext context) { return 어쩌구저쩌구위젯(); } }
Dart
복사
자식 위젯
ParentState parent = context.findAncestorStateOfType<ParentState>(); 코드를 build 메서드에 추가해서 parent에 있는 setState를 사용하면 된다.
class Child extends StatefulWidget { SearchBar(); ChildState createState() => ChildState(); } class ChildState extends State<Child> { Widget build(BuildContext context) { ParentState parent = context.findAncestorStateOfType<ParentState>(); return BlaBlaButton(text: Text('자식'), onTap: () { parent.setState() { parent.page += 1; } }); } }
Dart
복사
스택오버플로우를 보면 notifier 콜백 함수를 자식에게 전달해 부모 위젯의 state를 변경하는 방법도 있다. 하지만 이것도 더 상위의 부모의 state를 바꾸려면 함수를 전달하는 과정에서 drilling해야하고, 부모와 자식 위젯 둘 다 수정해주어야 한다.