Skip to content

Flutter FutureBuilder #
Find similar titles

Structured data

Category
Programming

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로 데이터가 제대로 들어왔는지 확인한다.

Image

비동기 함수 쓰는 곳 #

  • 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를 만드는 것을 신경 써야 한다.

참조링크 #

Suggested Pages #

0.0.1_20210630_7_v33