FutureBuilder

Future가 있는 위젯을 만들기위해선

Stateful 위젯으로 해둔 다음에,

로딩이 완료되면 그 값에 따라 setstate을 다시 해야했다. 

코드가 굉장히 지저분해지고, Stateful위젯이 강제된다는 점에서 불편하기도 했다.

이를 극복하기 위해 존재하는 위젯이 있는

바로 FutureBuilder를 사용하는 것이다.

FutureBuilder는 3가지의 요소를 갖는다.

child, future, builder이다.

future에 우리가 원하는 Future<T>를 return하는 메소드를 넣고,

builder에는 context와 snapshot을 인수로 갖고 위젯을 리턴하는 메소드를 넣으면된다.

(snapshot은 Future<T>의 return 값을 의미한다.)

그래서 future의 값에 따라 원하는데로 위젯을 build하도록 설정하면 알아서 값이 바뀔 때, 다시 build가 된다.

보통은 snapshot의 connectionState을 통해 waiting 또는 hasData 특성을 활용해서

future의 값이 도착하지 않았을때 로딩중임을 나타내는 위젯을 return하고

완료됐을 때를 기준으로 제대로된 위젯을 return하도록 코드를 짜둔다.

아, future builder는 우리가 설정해둔 future의 상태가 바뀔때마다 Futurebuilder의 buillder 부분이 다시 실행된다.

그래서 stateful 위젯을 통해 rebuild하는 것보다 효과적이긴 하지만, 아래 코드처럼 적은양의 코드는 사실상 큰 의미는 없다.

return Scaffold(
      appBar: AppBar(
          title: Text("Test"),
      body: FurtureBuilder(
          future : Provider.of(Orders, listen: false ).fetchAndSetOrders(),
          builder: ( ctx, dataSnapshot) {
               if( dataSnapshot.connectionState = ConnectionState.waiting) {
                   return Center( child: CircularProgressIndicator() );
               } else {
                  if( dataSnapshot.error != null {
                     return Center( 
                           child: Text("Error"),
                      );
                   } else {
                      return Consumer<Orders>(
                           builder: ( ctx, orderData, child) => ListView.builder(
                 itemCount: orderData.orders.length,
                 itemBuilder: ( ctx, i ) => OrderItem(orderData.orders[i]),
                 ), // ListView.builder
           ); // Consumer 
                  }  // end if 
              } // end if 
         } // end builder
       ) // FurtureBuilder
    ); // Scaffold