본문 바로가기
flutter

플러터 - InheritedWidget

by 들풀민들레 2023. 3. 13.

 

본 글은 [Do it! 깡샘의 플러터&다트 프로그래밍] 의 내용을 발췌한 것입니다.

 

 

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

이 절에서 살펴볼 InheritedWidget은 여러 위젯이 이용하는 상태를 가지는 상위 위젯을 만드는 클래스입니다. 위젯은 계층 구조를 이룹니다. 그리고 하위의 여러 위젯이 공통으로 이용하는 상태가 있다면 상위 위젯에서 상태를 관리하고 하위 위젯은 상위의 상태를 이용하는 식으로 작성하는 것이 좋습니다.
이미 살펴본 것처럼 하위의 공통 상태를 관리하는 상위 위젯을 StatefulWidget으로 만들고 하위에서 이 StatefulWidget의 상태 객체를 얻어서 이용하거나 상위의 함수를 이용하게 작성할 수 있습니다.

그런데 하위에서 공통으로 이용하는 상태를 가지는 InheritedWidget을 별도로 만들어서 제공할 수도 있습니다. InheritedWidget도 위젯입니다. 그런데 build() 함수는 없는 위젯입니다. 즉, 자체 화면을 만들지 않으며 단지 상태 데이터와 이를 관리하는 함수를 만들어 하위에서 이용할 수 있게 제공합니다.

InheritedWidget을 이용하려면 InheritedWidget을 상속받아 클래스를 만들고, 그 클래스에 하위 위젯에서 이용할 상태 데이터와 관리 함수를 선언합니다. InheritedWidget은 자체 화면을 만들지 않으므로 StatelessWidget이나 StatefulWidget을 상속받아 작성하는 위젯보다 단순합니다. 하위에서 이용할 상태와 관리 함수를 선언해 주면 됩니다.
다음 코드에서는 count와 increment() 함수를 선언했습니다.

class MyInheritedWidget extends InheritedWidget {
    int count = 0; // 하위 공유 데이터
    MyInheritedWidget(child) : super(child: child);//1
    increment() { // 하위에서 호출할 함수
    	count++;
    }
    @override
    bool updateShouldNotify(MyInheritedWidget oldWidget) => true;//2
    
    static MyInheritedWidget? of(BuildContext context) =>
   		context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();//3
}

1번 코드는 InheritedWidget의 생성자입니다. InheritedWidget은 자체 build() 함수를 가지지 않으므로 위젯 계층 구조에서 자신의 하위에 위치할 위젯을 생성자의 매개변수로 받아 상위 생성자에 전달합니다. 결국 super()에 매개변수로 지정하는 위젯이 자신의 하위 위젯이며, 이 위젯부터 그 하위에 있는 모든 위젯이 InheritedWidget의 상태를 이용할 수 있습니다.
그리고 InheritedWidget이 자신의 상위 위젯에서 다시 생성될 때가 있습니다. 이때 Inherited Widget의 하위 위젯을 다시 빌드할지 판단해야 하는데
2번 코드의 updateShouldNotify() 함수가 그 역할을 합니다.
예를 들어 오른쪽 그림과 같은 계층 구조로 InheritedWidget을 이용한다고 생각해 보겠습니다.

위젯 계층 구조에서 InheritedWidget 상위에 ParentWidget이 있다면 ParentWidget의 상태 변경에 따라 InheritedWidget이 다시 생성될 수 있습니다. 그러면 일반적으로 그 하위 위젯도 다시 빌드해야 합니다. 하지만 InheritedWidget은 상태만 가지는 위젯이므로 자신은 다시 생성되지만 하위 위젯은 다시 빌드할 필요가 없을 수도 있습니다. 예를 들어 자신이 생성되었더라도 자신이 가지는 상태 데이터가 이전과 같다면 하위 위젯을 다시 빌드할 필요는 없습니다.
자신이 다시 생성될 때 자동으로 호출되는 updateShouldNotify() 함수로 하위 위젯을 다시 빌드할지 정합니다. 이 함수의 반환값이 true이면 하위 위젯을 다시 빌드하며, false이면 다시 빌드하지 않습니다. updateShouldNotify() 함수의 매개변수는 이전 InheritedWidget 객체이며 이전 객체의 값과 현재 자신이 가진 값을 비교해서 true나 false를 반환하면 됩니다.
3번 코드에서 of() 함수는 InheritedWidget의 하위 위젯이 InheritedWidget의 객체를 얻으려고 호출하는 함수입니다. 객체를 생성하지 않고 호출해야 하므로 static 함수로 선언합니다. of() 함수는 하위 위젯에서 이용할 InheritedWidget을 반환해야 하는데 이때 dependOnInheritedWidgetOfExactType()이라는 함수를 사용했습니다. 이 함수는 위젯 계층 구조에서 of() 함수를 호출한 위젯과 가장 가까운 InheritedWidget을 반환해 줍니다.
InheritedWidget의 하위 위젯이 InheritedWidget을 이용하려면 InheritedWidget에서 제공하는 of() 함수를 호출하면 됩니다. 그러면 위젯 계층 구조에 있는 InheritedWidget 객체가 전달되므로 이 객체를 이용해 필요한 데이터나 함수를 이용하면 됩니다.

int count = MyInheritedWidget.of(context)!.count;

 

 

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

 

 

'flutter' 카테고리의 다른 글

플러터 - Bloc Cubit  (0) 2023.03.13
플러터 - Provider  (0) 2023.03.13
플러터 - Isolate  (0) 2023.03.13
플러터 - Future, FutureBuilder  (0) 2023.03.13
플러터 - dio  (0) 2023.03.13