Wednesday, July 26, 2023

Flutter의 FutureBuilder와 StreamBuilder 차이점 알아보기

Flutter의 FutureBuilder와 StreamBuilder 이해하기

이 글에서는 Flutter의 핵심 위젯인 FutureBuilderStreamBuilder에 대해 알아보겠습니다. 이 두 위젯이 어떻게 동작하는지, 어떻게 사용되는지, 그리고 어떤 경우에 사용하는 것이 좋은지에 대한 정보와 예시를 제공하겠습니다.

FutureBuilder란 무엇인가?

FutureBuilder는 Flutter에서 Future 객체를 이용하여 위젯의 상태를 업데이트하는데 사용합니다. 이 위젯은 비동기 작업의 결과를 화면에 표시하는데 유용하며, Future 객체를 build 메소드 내에서 활용 가능하게 해줍니다.

FutureBuilder<T>({
  Key? key,
  required Future<T> future,
  required AsyncWidgetBuilder<T> builder,
})

StreamBuilder란 무엇인가?

StreamBuilderStream을 기반으로 위젯의 상태를 업데이트하는 Flutter 위젯입니다. 스트림에서 데이터를 읽어올 때마다 위젯의 상태가 자동으로 업데이트되고, 하나의 스트림에서 여러 개의 이벤트를 처리할 수 있습니다.

StreamBuilder<T>({
  Key? key,
  T? initialData,
  required Stream<T> stream,
  required AsyncWidgetBuilder<T> builder,
})

FutureBuilder와 StreamBuilder의 차이점 이해하기

이번 장에서는 FutureBuilder와 StreamBuilder의 차이점과 각각 어떤 상황에서 적합하게 사용될 수 있는지에 대해 설명하겠습니다.

데이터 처리 방식의 차이

FutureBuilder단일 결과 값의 연산을 처리하는 데 적합합니다. 예를 들어, REST API 호출을 통한 데이터 조회와 같은 일회성 요청을 처리하게 됩니다.

반면에, StreamBuilder지속적인 데이터 이벤트 처리에 적합합니다. 웹소켓 통신이나 파일 업로드 진행 상황 표시 등 지속적인 데이터 스트림을 처리할 때 사용됩니다.

Connection State의 차이점

FutureBuilder와 StreamBuilder는 비동기 작업의 상태를 ConnectionState를 통해 관리합니다. 하지만, 이 두 위젯이 ConnectionState를 처리하는 방식에는 약간의 차이가 있습니다.

  1. FutureBuilder는 연산이 완료되면 ConnectionState.done 상태가 됩니다.
  2. StreamBuilder는 스트림이 완료되지 않은 경우에는 ConnectionState.active 상태를 유지하고, 스트림이 완료되면 ConnectionState.done 상태가 됩니다.

FutureBuilder와 StreamBuilder의 사용 예시

다음은 FutureBuilder와 StreamBuilder의 사용방법과 그 차이를 이해하는데 도움이 될 예시입니다.

FutureBuilder 사용 예시

FutureBuilder<String>(
  future: fetchDataFromApi(),
  builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
    if (snapshot.connectionState == ConnectionState.done) {
      return Text(snapshot.data ?? 'No data found');
    } else {
      return CircularProgressIndicator();
    }
  },
)

StreamBuilder 사용 예시

StreamBuilder<String>(
  stream: streamDataFromWebSocket(),
  builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
    if (snapshot.connectionState == ConnectionState.active) {
      return Text(snapshot.data ?? 'No data received');
    } else {
      return CircularProgressIndicator();
    }
  },
)

FutureBuilder와 StreamBuilder의 성능 향상 및 최적화 팁

이번 장에서는 FutureBuilder와 StreamBuilder의 성능을 향상시키고 개발 프로세스를 개선하기 위한 몇 가지 팁을 제공하겠습니다.

Provider 패키지를 이용한 상태관리

Provider 패키지를 통해 상태 관리를 캡슐화하고 효율적으로 행할 수 있습니다. 이를 통해 불필요한 위젯 리빌드를 줄이고 앱의 전반적인 성능을 향상시킬 수 있습니다.

비동기 작업의 분리

가능한 경우, 비동기 작업을 별도의 메소드나 서비스로 분리하여 코드를 깔끔하게 구성하고, 디버깅과 테스트를 용이하게 하며 가독성을 향상시킬 수 있습니다.

에러 처리

FutureBuilder와 StreamBuilder에서 발생하는 예외 및 에러를 적절하게 처리해야 합니다. builder 내에서 snapshot.hasError를 이용해 에러 발생 여부를 확인하고, 사용자에게 적절한 에러 메시지를 표시하거나 로그를 작성하는 등의 작업을 수행할 수 있습니다.

데이터 캐싱

필요에 따라, 서버에서 가져온 데이터를 캐시하여 재사용할 수 있습니다. 이 방법은 동일한 요청을 여러 번 반복해서 호출하는 대신 앱의 로딩 시간과 데이터 사용량을 줄일 수 있습니다. 이 작업을 도와주는 다양한 패키지들이 있으며, 개발자의 요구에 맞게 커스터마이징할 수 있습니다.

디버그 모드에서의 성능 분석

앱의 성능 문제는 디버그 모드에서 쉽게 분석할 수 있습니다. Flutter는 디버그 모드에서 성능 상의 문제를 찾는 몇 가지 도구를 제공하며, 이를 활용하여 개발 프로세스를 개선할 수 있습니다.

FutureBuilder와 StreamBuilder의 실제 사용 사례

이번 장에서는 Flutter 애플리케이션에서 FutureBuilder와 StreamBuilder를 활용하는 실제 사례를 통해 각각의 사용법을 설명하겠습니다.

FutureBuilder를 활용한 REST API 호출 처리

FutureBuilder를 활용하여 REST API 호출을 수행하고 그 결과를 화면에 표시하는 예제입니다.

<Your StatefulWidget>
Future<List<Post>> _fetchPosts() async {
  final response = await http.get('https://jsonplaceholder.typicode.com/posts');
  if (response.statusCode == 200) {
    List jsonResponse = json.decode(response.body);
    return jsonResponse.map((post) => Post.fromJson(post)).toList();
  } else {
    throw Exception('Failed to load posts');
  }
}

Widget _buildPostList(BuildContext context, List<Post> posts) {
  // Build a list of ListTile widgets from the list of Post objects
}

Widget build(BuildContext context) {
  return FutureBuilder<List<Post>>(
    future: _fetchPosts(),
    builder: (BuildContext context, AsyncSnapshot<List<Post>> snapshot) {
      if (snapshot.connectionState == ConnectionState.done) {
        return _buildPostList(context, snapshot.data!);
      } else {
        return CircularProgressIndicator();
      }
    },
  );
}

StreamBuilder를 활용한 댓글 스트리밍 처리

댓글 스트리밍 처리를 위한 StreamBuilder 사용 예제입니다.

<Your StatefulWidget>
Stream<List<Comment>> _getCommentStream() {
  // Implement a function that returns a Stream of a List of Comment objects
}

Widget _buildCommentList(BuildContext context, List<Comment> comments) {
  // Build a list of ListTile widgets from the list of Comment objects
}

Widget build(BuildContext context) {
  return StreamBuilder<List<Comment>>(
    stream: _getCommentStream(),
    builder: (BuildContext context, AsyncSnapshot<List<Comment>> snapshot) {
      if (snapshot.connectionState == ConnectionState.active) {
        return _buildCommentList(context, snapshot.data!);
      } else {
        return CircularProgressIndicator();
      }
    },
  );
}

0 개의 댓글:

Post a Comment