티스토리 뷰

가장 기본적인 State를 참조할 수 있는 방법에 대해 알아보도록 하겠습니다.

 

먼저 특정 부모 위젯의 State를 참조하는 방법은 간단합니다.

 

class ExampleWidget extends StatefulWidget {
  const ExampleWidget({super.key});
	
  /// Context 중 제네닉 타입으로 정의된 State의 가장 가까운 부모 위젯을 반환합니다.
  static State<ExampleWidget>? of(BuildContext context) {
    return context.findAncestorStateOfType<ExampleWidgetState>();
  }

  @override
  State<ExampleWidget> createState() => ExampleWidgetState();
}

 

Current의 State는 ExampleWidgetState 입니다.

context.findAncestorStateOfType<ExampleWidgetState>();

해당 코드를 사용하여 Context의 부모 위젯 중 제네릭 타입으로 정의된 State를 반환합니다.

Current와 Parent는 제네릭 타입으로 정의된 State가 아니므로 Grand Parent의 State를 반환합니다.

 

반대로 자식 위젯의 State를 참조하는 방법도 간단합니다.

 

// 현재 노드와 자식 노드들만을 순회하여 위젯 트리를 방문합니다.
//
// 현재 노드의 자식 노드 -> 자식의 자식 노드
context.visitChildElements()

// 현재 노드와 현재 노드의 자식 노드들을 모두 순회하여 위젯 트리를 방문합니다.
//
// 현재 노드 -> 현재 노드의 자식 노드 -> 자식의 자식 노드
context.visitChildren()

 

여기서 노드(Node)는 트리 구조에서 하나의 데이터를 담고 있는 단위를 의미합니다,

여기서는 위젯(Widget)이랑 요소(Element)을 말하는 것과 같습니다.

 

두 메소드는 위 코드 처럼 사용하는 목적에 따라 다르게 사용하니까 그 점 알아두시기 바랍니다.

 

/// 자식 위젯인 [ExampleWidget]의 State를 참조하기 위해 그 하위 위젯들을 방문합니다.
void _visitor(Element element) {
  // 하위 위젯을 참조하고 정의합니다.
  final widget = element.widget;
   
  // 해당 하위 위젯이 ExampleWidget이라면 해당 위젯의 State를 참조합니다.
  if(widget is ExampleWidget) {
    // RunType을 StatefulElement으로 정의하여 상태를 참조할 수 있도록 합니다.
    final statefulElement = element as StatefulElement;
	
    final state = statefulElement.state as ExampleWidgetState;
  }
  
  // 참조한 하위 위젯의 하위 위젯에게 똑같은 방식으로 검색을 수행합니다.
  element.visitChildElements(_visitor);
}





@override
void initState() {
  super.initState();
  
  // 화면을 그리고 있으면 해당 작업이 완료 된 후 해당 함수를 호출합니다.
  WidgetsBinding.instance.addPostFrameCallback((_) => context.visitChildElements(_visitor));
}