WHY DOES IT NEED?
Root 위젯에 어떠한 데이터(state)가 있다고 가정하자, 이때 가장 아래에 있는 주황색 위젯에서 이를 필요로 하는 경우에 귀찮은 일이 생긴다.
주황색 위젯에 이 데이터(state)를 넘겨주기 위해 중간과정의 모든 위젯의 생성자에 state 데이터를 인자로 건네 주어야 한다.
이를 위해 나온 해결책이 바로 Inherited Widget
가장 위젯트리 최상단에 Inherited 위젯을 놓고 데이터를 저장하면 자식 위젯들은 이를 어디서든지 바로 접근이 가능합니다.
HOW TO USE?
자식위젯에서 저 Inherited Widget을 어떻게 접근 할까? → of 메소드 사용
class PhotoProvider extends InheritedWidget {
final PixabayApi api; // 하위 위젯트리에 전달하고자 하는 객체
const PhotoProvider({
Key? key,
required this.api,
required Widget child,
}) : super(key: key, child: child);
static PhotoProvider of(BuildContext context) {
final PhotoProvider? result =
context.dependOnInheritedWidgetOfExactType<PhotoProvider>();
assert(result != null, 'No PixabayApi found in context');
return result!;
}
bool updateShouldNotify(PhotoProvider oldWidget) {
// TODO: implement updateShouldNotify
return oldWidget.api != api; // 객체가 같은 경우 변경을 하위 위젯에 알리지 않음
}
}
Dart
복사
1.
InheritedWidget 상속받기
2.
of 함수 정의
3.
updateShouldNotify 재정의
이 함수는 oldvalue 와 new value를 비교해서 위젯이 redraw 되도록 해 주는 value값을 지정해 주는 메소드입니다.
class MainApp extends StatelessWidget {
const MainApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PhotoProvider( // 호출부에서 api와 함께 생성
api: PixabayApi(),
child: const HomeScreen(),
));
}
}
Dart
복사
이렇게 하면 하위 위젯트리에서 api에 접근할 수 있다.
//@override
// Widget build(BuildContext context) {
// ...
final photoProvider = PhotoProvider.of(context); // 상위 위젯의 객체 가져옴
final photos = await photoProvider.api.fetch(_controller.text);
Dart
복사
이렇게 가져온 photoProvider(InheritedWidget) 안의 api 객체에 접근이 가능해진다.
context 를 통해 데이터를 가져와야 하기 때문에, build 메서드 안에서 가져와준다.
MUST KNOW ABOUT
1.
사실 일부 많은 위젯들은 Inherited Widget 이다.
대표적인 예로 Scaffold 위젯, Theme 위젯, FocusScope 위젯이 있다.
→ 저 위젯들이 부모 위젯에 있으면 of 메소드로 접근할 수 있다.
2.
Provider 또한 아까 처음에 가정한 문제상황을 해결하기 위한 패키지.
자식 위젯들이 특정 최상단 데이터에 바로 접근 해 줄 수 있도록 해 주는 라이브러리