FutureBuilder<T> class
Future 와의 상호작용에 대한 최신 스냅샷을 기반으로 자체적으로 빌드되는 위젯입니다.
공식 문서 코드
FutureBuilder 는 비동기 작업의 결과를 기다렸다가, 그 결과에 따라 UI 를 업데이트시켜주는 위젯이다.
솔직히 공식 문서나 영상을 봐도 이해가 바로 가진 않을 것인데 쉽게 풀어서 설명해 보도록 하겠다.
1. 사용처
서버에서 데이터를 받아와서 화면에 보여주는 상황
서버에서 데이터를 받아오게 되면 필연적으로 지연(딜레이)이 되기 마련이다. 이럴 때에 보통의 앱은 인디케이터(로딩바)를 보여주게 되는데 FutureBuilder 가 그 동작을 도와준다고 생각하면 된다.
2. 작동 방식
FutureBuilder는 Future라는 비동기 작업을 받는다. 그런 후 그 Future 가 완료될 때까지 기다리게 되는데 이 동작이 완료되면 (로딩에 성공했는 실패 했든) builder 함수가 호출돼서 UI 를 다시 그려준다.
다시 말해서 비동기 작업을 기다렸다가 결과에 따라서 화면을 업데이트한다는 말이다.
3. 규칙
Future 는 builder() 함수 안에서 직접 만들면 안 된다. 그 이유로는 build 는 자주 불릴 수 있어서 비동기 작업이 계속해서 다시 시작되기 때문이다. 그니까 겁나게 비효율적이고 앱이 느려질 수 있다는 거다.
그래서 iniState 같은 곳에서 미리 만들어서 변수를 저장해 두고 사용해야 한다.
late Future<String> myFuture;
@override
void initState() {
super.initState();
myFuture = fetchData();
}
그렇다면 builder 는 언제 호출되나 하면
- Future가 아직 완료 안 됐을 때 → waiting 상태
- Future가 성공적으로 완료됐을 때 → done 상태 (data 포함)
- Future가 에러로 실패했을 때 → done 상태 (error 포함)
이런 상황에서 호출이 된다. 그니까 그냥 데이터 불러오기 전까지는 계속 호출된다고 생각하면 편하다.
예시 코드를 한번 봐보고 하위 속성을 봐보자.
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 2));
return 'Hello from the future!';
}
class MyFutureWidget extends StatelessWidget {
final Future<String> myFuture;
MyFutureWidget({required this.myFuture});
@override
Widget build(BuildContext context) {
return FutureBuilder<String>(
future: myFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator(); // 로딩 중
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}'); // 에러 발생
} else if (snapshot.hasData) {
return Text('Data: ${snapshot.data}'); // 성공적으로 데이터 수신
} else {
return Text('Something went wrong');
}
},
);
}
}
이런 식으로 사용하면 될 것이다.
하위 속성
속성명 | 타입 | 기본값 | 설명 |
future | Future<T>? | null | 완료 후 결과를 전달할 비동기 작업 |
initialData | T? | null | future가 완료되기 전까지 임시로 사용할 데이터 |
builder | AsyncWidgetBuilder <T> | - | 현재 상태를 기반으로 위젯을 생성하는 함수 |
debugRethrowError | static bool | false | 디버깅 모드에서 오류 발생 시 예외를 다시 발생시킬지 여부 |
하위 속성 요약을 하자면 FutureBuilder는 future와 연결되어 비동기 작업의 진행 상태를 추적하는 위젯이고 builder는 AsyncSnapshot 이라는 객체를 받아서 현재 상태에 따라 적절한 위젯을 반환한다.
AsyncSnapshot.connectionState는 다음 중 하나이다.
- none: future가 없음
- waiting: future는 있지만 아직 완료되지 않음
- done: future가 완료됨 (성공 또는 실패)
그리고 이는 builder 의 호출을 판별하는 역할을 한다.
암튼 이 정도로 정리할 수 있겠다.
이번에는 FutureBuilder 에 대해서 알아봤는데 확실히 아직 공부할게 많이 남았다는 걸 여실히 느끼게 해주는 것 같다.
그럼 도움이 되었길 바라며 마치겠다.