Flutter의 FutureBuilder 강의 요약 및 설명

pharmDev·2024년 12월 9일

FutureBuilder는 비동기 작업의 결과를 UI에 반영하기 위해 사용하는 Flutter 위젯입니다. 주로 API 호출, 파일 읽기, 데이터베이스 접근 등 시간이 소요되는 작업에서 사용됩니다. 강의 내용을 기반으로 FutureBuilder를 정리하고 설명을 덧붙이겠습니다.


1. FutureBuilder의 기본 구조

FutureBuilder는 비동기 작업(Future)의 상태에 따라 UI를 동적으로 렌더링합니다.

예시 코드

import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('FutureBuilder Example')),
        body: FutureBuilderExample(),
      ),
    );
  }
}

class FutureBuilderExample extends StatefulWidget {
  
  _FutureBuilderExampleState createState() => _FutureBuilderExampleState();
}

class _FutureBuilderExampleState extends State<FutureBuilderExample> {
  // 비동기 작업 함수 정의
  Future<int> fetchNumber() async {
    await Future.delayed(Duration(seconds: 3)); // 3초 지연
    return Random().nextInt(100); // 0~99 랜덤 숫자 반환
  }

  
  Widget build(BuildContext context) {
    return FutureBuilder<int>(
      future: fetchNumber(), // 실행할 Future
      builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
        // 스냅샷의 상태에 따라 UI 분기 처리
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(child: CircularProgressIndicator());
        } else if (snapshot.hasError) {
          return Center(child: Text('Error: ${snapshot.error}'));
        } else if (snapshot.hasData) {
          return Center(child: Text('Number: ${snapshot.data}'));
        } else {
          return Center(child: Text('No Data'));
        }
      },
    );
  }
}

2. 주요 개념 및 동작 방식

(1) FutureBuilder 기본 개념

  • future: 비동기 작업(Future 객체)을 전달합니다.
  • builder: UI를 렌더링하는 콜백 함수. 비동기 작업의 상태를 나타내는 AsyncSnapshot을 사용합니다.

(2) AsyncSnapshot

AsyncSnapshot은 비동기 작업의 현재 상태와 데이터를 제공합니다.

  • connectionState: 작업 상태를 나타냅니다.
    • none: Future가 초기화되지 않음.
    • waiting: 작업 대기 중.
    • active: 스트림이 활성 상태(스트림 빌더에서 주로 사용).
    • done: 작업 완료.
  • hasData: 데이터가 있는지 여부.
  • hasError: 에러 발생 여부.
  • data: 비동기 작업에서 반환된 데이터.
  • error: 에러 내용.

(3) FutureBuilder 사용 시 주요 패턴

  • 에러 처리: snapshot.hasError를 통해 에러 상태를 처리.
  • 데이터 확인: snapshot.hasData로 데이터 존재 여부 확인.
  • 연결 상태에 따른 처리: snapshot.connectionState에 따라 상태 분기.

3. 연결 상태(ConnectionState) 설명

ConnectionState는 Future나 Stream의 상태를 나타냅니다.

상태설명UI 예제
noneFuture가 초기화되지 않음."No Future Provided"
waitingFuture 작업 대기 중.로딩 스피너
activeStream에서 데이터를 지속적으로 수신.현재 진행 중(스트림 전용).
done작업 완료.데이터 출력

연결 상태 출력 코드

print('Connection State: ${snapshot.connectionState}');

4. FutureBuilder를 사용할 때 유의할 점

(1) 제너릭 타입 명시

Future와 AsyncSnapshot의 타입을 명시하면 코드 자동 완성과 타입 안정성을 높일 수 있습니다.

FutureBuilder<int>(
  future: fetchNumber(),
  builder: (context, AsyncSnapshot<int> snapshot) { ... }
);

(2) 에러 처리

Future에서 에러를 발생시키는 경우 UI에서 적절히 처리해야 합니다.

Future<int> fetchWithError() async {
  await Future.delayed(Duration(seconds: 3));
  throw Exception('An error occurred');
}

5. FutureBuilder의 동작 흐름 디버깅

Future의 상태가 변경될 때마다 builder가 다시 실행됩니다. 디버깅을 위해 snapshot.datasnapshot.connectionState를 출력하면 동작을 확인할 수 있습니다.

예제

builder: (context, AsyncSnapshot<int> snapshot) {
  print('Connection State: ${snapshot.connectionState}');
  print('Data: ${snapshot.data}');
  ...
}

6. FutureBuilder의 캐싱 동작

FutureBuilder는 동일한 Future를 여러 번 실행하지 않고 데이터를 캐싱합니다. 하지만 부모 위젯이 다시 빌드되면 Future를 다시 실행합니다.


7. 요약

FutureBuilder는 다음의 세 가지 핵심 패턴을 이해하면 쉽게 사용할 수 있습니다:
1. 연결 상태에 따라 분기 처리: snapshot.connectionState.
2. 에러 처리: snapshot.hasErrorsnapshot.error.
3. 데이터 처리: snapshot.hasDatasnapshot.data.

FutureBuilder를 활용하면 비동기 작업의 상태를 UI에 쉽게 반영할 수 있습니다. 다음 시간에는 StreamBuilder를 다루며 실시간 데이터 처리에 대해 알아볼 수 있습니다.

profile
코딩을 배우는 초보

0개의 댓글