다음과 같은 코드가 있다고 가정하자.
// main.dart
void main() {
runApp(const App());
}
class App extends StatelessWidget {
const App({super.key});
Widget build(BuildContext context) {
return Container();
}
}
// home_screen.dart
class HomeScreen extends StatefulWidget {
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<WebtoonModel> webtoons = [];
bool isLoading = true;
void waitForWebtoons() async {
webtoons = await ApiService().getTodaysToons();
setState(() {
isLoading = false;
});
}
void initState() {
super.initState();
waitForWebtoons();
}
}
HomeScreen 내부의 코드를 살펴보면, initState시 waitForWebtoons를 호출한다. 여기서 waitForWebtoons는 Future를 반환하는 코드이다.
이렇게 됐을 때, 동작 순서가 어떻게 되는지 정리해보자.
먼저, main의 build 메서드가 호출된다. build가 호출되고 나면 homeScreen 내부의 initState가 호출되면서 그 내부의 waitForWebtoons가 호출된다.
이 때, 아직 waitForWebtoons의 응답이 오지 않았으므로 해당 메서드는 Future를 반환하게 되고, build 메서드를 바로 실행한다.
후에 waitForWebtoons로부터 데이터가 전달되어 Future가 채워지면, isLoading=false 및 setState 메서드를 호출하게 되고, setState의 호출로 build가 훅되어 re-render된다.
끝!