본문 바로가기

개발 이야기/flutter

[Flutter] 자식 위젯에서 부모 위젯 state 참조하는 방법 | findAncestorStateOfType

image source: flutter.ko-dev

 

 

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

자기 자신의 state를 업데이트하려면 setState를 쓰면 된다. 하지만 자식이 부모 위젯의 state를 변경하려면 어떻게 해야할까?

 

 

 

How to Set/Update State of StatefulWidget from other StatefulWidget in Flutter?

For Example in the below code plus button works and able to update the text but the minus button does not. But if we press FloatingActionButton then the State is refreshed . The minus button is cha...

stackoverflow.com

스택오버플로우에 질문이 올라왔고 질문자와 55명의 up vote를 받은 답변은 이러했다.

 

  • OLD: _MyHomePageState의 글로벌 인스턴스를 생성해서 자식 Stateful Widget에서 _myHomePageState.setState로 사용해라.
  • NEW: 글로벌 인스턴스로 생성할 필요 없이 부모 인스턴스를 자식 위젯에 전달해라.

옛날 방법은 글로벌 인스턴스를 생성한다는 점, 새로운 방법은 인스턴스 하나를 통째로 넘긴다는 점에서 둘 다 별로 좋아보이지 않는다. 또한, 바로 위의 부모가 아니라 더 상위 부모의 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 {
  @override
  ParentState createState() => ParentState();
}

class ParentState extends State<Parent> {
  int page = 1;

  @override
  Widget build(BuildContext context) {
    return 어쩌구저쩌구위젯();
  }
}

 

 

 

"자식 위젯"

 

ParentState parent = context.findAncestorStateOfType<ParentState>(); 코드를 build 메서드에 추가해서 parent에 있는 setState를 사용하면 된다.

class Child extends StatefulWidget {
  SearchBar();

  @override
  ChildState createState() => ChildState();
}

class ChildState extends State<Child> {
  @override
  Widget build(BuildContext context) {
    ParentState parent = context.findAncestorStateOfType<ParentState>();

    return BlaBlaButton(text: Text('자식'), onTap: () {
      parent.setState() {
        parent.page += 1;
      }
    });
  }
}

 

 

스택오버플로우를 보면 notifier 콜백 함수를 자식에게 전달해 부모 위젯의 state를 변경하는 방법도 있다. 하지만 이것도 더 상위의 부모의 state를 바꾸려면 함수를 전달하는 과정에서 drilling해야하고, 부모와 자식 위젯 둘 다 수정해주어야 한다.