Flutter
FutureBuilder
#
Find similar titles
- (rev. 6)
- jhjeon
Structured data
- Category
- Programming
Table of Contents
FutureBuilder #
FutureBuilder란? #
FutureBuilder는 비동기 함수에서 리턴하는 Future<변수> 받아 먼저 Build하고 비동기 함수 계산이 완료되면 실제 리턴 값을 보여준다. 주로 JSON 파일과 같이 데이터 통신에 주로 쓰인다.
비동기 함수의 간단한 정리 #
예를 들어 API와 통신을 할 때 서버와 모바일 기기는 데이터를 대표적으로 JSON으로 통신한다. 데이터 단위가 크면 클수록 서버에서 기기로 송신하고 수신하는 데 시간이 오래 걸린다. 이때 모바일 기기 입장에서 다른 일도 많은데(사용자 이벤트 처리 - 탭, 스크롤 등)이 데이터 수신만 기다릴 수 없다. 따라서 기기는 다른 일을 먼저 처리하고(UI 빌드) 만약 데이터가 완전하게 도착하면 그때 미뤄왔던 일을 처리한다. 앱 사용자들은 이 모든 과정을 로딩 화면으로 인식한다.
FutureBuilder 특징 #
FutureBuilder(
future: ParsingHealthData(gapDays), //비동기 함수(JSON 수신 등)
builder: (BuildContext context, AsyncSnapshot snapshot) {
//ConnectionState.done은 비동기 데이터 수신이 완료되었다는 의미
if(snapshot.connectionState == ConnectionState.done){
todayDataSet.healthTotalData = snapshot.data;
todayDataSet.isSynced = true;
//5초 지나서 MyHomePage 클래스로 이동하라는 의미
Future.delayed(Duration(seconds: 5), () {
// 5 seconds over, navigate to Page 2.
Navigator.of(context).pushAndRemoveUntil(
FadePageRoute(
duration: 600,
barrier: Colors.black,
builder: (_) => MyHomePage(),
),
(route) => false);
});
}
return Container(); //비동기 함수가 완료되었을 때 보여지는 UI
-
FutureBuilder는 build의 리턴 값으로 주로 쓰이고 매개변수로 future와 builder를 갖는다.
-
future 매개변수에는 Future 변수를 리턴하는 함수가 들어가야 한다.
-
builder에는 BuildContext와 AsyncSnapshot을 받는 함수가 들어가야 한다.
-
ConnectionState로 데이터가 제대로 들어왔는지 확인한다.
비동기 함수 쓰는 곳 #
-
OnWillPop(안드로이드 뒤로가기 버튼)함수와 같이 사용자의 이벤트를 기다리는 부분에도 비동기 함수가 쓰인다.
-
StreamBuilder에서 같이 영상 스트림 데이터, FutureBuilder에서 이미지, JSON 파일에서 쓰인다.
-
Firebase Console Messaging과 같이 알람 기능에도 사용된다.
FutureBuilder와 AsyncSnapshot #
데이터가 Future로 들어올 때 우리는 빈 상자를 받고 비동기 함수 연산이 완료되면 값을 돌려받는다고 이야기했었다. 이때 boolean 값으로 데이터가 다 들어왔는지, 에러가 생겼는지 확인할 수 있다. 아래에 있는 조건들은 들어오는 데이터에 따라 true, false로 표현된다.
종류 | 코드 | 값 | 의미 |
---|---|---|---|
ConnectionState.done | snapshot.connectionState == ConnectionState.done | true or false | 데이터 전체가 들어왔는지? |
ConnectionState.active | snapshot.connectionState == ConnectionState.done | true or false | 데이터가 들어오기 시작되었는지?(일부라도 들어오면 true) |
ConnectionState.none | snapshot.connectionState == ConnectionState.done | true or false | 데이터가 아직 들어오지 않았는지? |
ConnectionState.waiting | snapshot.connectionState == ConnectionState.done | true or false | 아직 데이터가 안 들어왔고 들어오길 기다리는 중인지? |
ConnectionState로 데이터 상태를 확인하는 방법 말고도 snapshot.haserror나 snapshot.hasdata로 현재 들어온 데이터가 에러인지, 정상적으로 들어왔는지 확인할 수 있다.
종류 | 코드 | 값 | 의미 |
---|---|---|---|
snapshot.hasdata | if(snapshot.hasdata == true) | true or false | 데이터가 정상적으로 들어왔는지? |
snapshot.haserror | if(snapshot.hasdata == true) | true or false | 들어온 데이터가 에러가 있는지? |
FutureBuilder에서 위에 있는 조건 값에 충족하면 UI는 즉시 다시 빌드된다. 이를 통해 로딩 화면을 보여준 후 개발자가 원하는 화면으로 자연스럽게 이동시킬 수 있다.
FutureBuilder에서 주의할 점 #
FutureBuilder에서 주의할 점은 stateful 클래스일 때 특히 스트롤하는 UI일 때 계속 Rebuild 되는 문제점이 있다. 다시 말해 FutureBuilder의 매개변수 future에 명시하는 비동기 함수가 반복해서 실행될 수 있다. 이 문제를 해결하기 위해서는 비동기 함수를 initState에 선언하면 문제가 해결된다.
void initState(){
super.initState();
//set_sync_and_display는 비동기 함수이다.
lifelogData = set_sync_and_display(
context,
widget.healthData.isIOSHealthAppOperate,
widget.healthData.loadingDays,
_memoizer);
}
FutureBuilder(
future: lifelogData,
builder: (BuildContext context, AsyncSnapshot snapshot){
return Container();
}
initState()는 클래스가 생성될 때 한 번만 선언된다. 따라서 다른 위젯이 계속 빌드 되어도 비동기 함수는 한 번만 작동한다.
정리 #
FutureBuilder와 StreamBuilder는 앱이 네트워크 통신할 때 매우 자주 그리고 중요하게 이용된다. 따라서 비동기 함수 개념과 async, await의 의미를 잘 알고 사용해야 한다. 그리고 데이터가 들어오는 상태에 따라 오류 대응을 잘 해주어야 한다. 그러기 위해서는 ConnectionState의 값에 따라 대응하는 UI를 만드는 것을 신경 써야 한다.
참조링크 #
- https://www.youtube.com/watch?v=ek8ZPdWj4Qo
- https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
- https://api.flutter.dev/flutter/widgets/ConnectionState-class.html
Suggested Pages #
- 0.025 Android
- 0.025 iOS
- More suggestions...