Flutter에서 데이터를 비동기적으로 가져오는 두 가지 방법

Odyssey·2024년 10월 10일

flutter_study

목록 보기
3/9
post-thumbnail

Flutter에서 데이터를 비동기적으로 가져올 때, Stateful 위젯에서 async/await를 사용하거나 Stateless 위젯에서 FutureBuilder를 사용하는 두 가지 접근 방식이 있다. 이 두 가지 방법은 각각의 장단점이 있으며, 어떤 상황에 적합한지에 따라 선택해야 한다.

1. Stateful 위젯에서 async/await 사용

Stateful 위젯에서는 데이터를 받아오기 위해 initState() 메서드에서 async/await를 사용하여 비동기 작업을 수행하는 것이 일반적이다.

예제 코드

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Stateful Widget Async Await')),
        body: DataFetchExample(),
      ),
    );
  }
}

class DataFetchExample extends StatefulWidget {
  
  _DataFetchExampleState createState() => _DataFetchExampleState();
}

class _DataFetchExampleState extends State<DataFetchExample> {
  String data = 'Fetching data...';

  
  void initState() {
    super.initState();
    fetchData();
  }

  Future<void> fetchData() async {
    try {
      final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
      if (response.statusCode == 200) {
        setState(() {
          data = jsonDecode(response.body)['title'];
        });
      } else {
        setState(() {
          data = 'Failed to load data';
        });
      }
    } catch (e) {
      setState(() {
        data = 'Error occurred: $e';
      });
    }
  }

  
  Widget build(BuildContext context) {
    return Center(
      child: Text(data),
    );
  }
}

Stateful 위젯에서 async/await 사용의 특징

  • 상태 관리: Stateful 위젯은 내부 상태를 관리할 수 있어, 데이터를 가져오는 동안 상태를 쉽게 업데이트하고 UI를 다시 빌드할 수 있다.
  • initState() 활용: 데이터를 초기화할 때 initState() 메서드에서 async 작업을 수행하기 때문에 비동기 작업이 자동으로 시작된다.

장점

  1. 유연성: 여러 비동기 작업을 순차적으로 수행하거나 동적으로 상태를 관리할 때 유리하다.
  2. 명확한 상태 관리: setState()를 사용하여 UI의 상태를 명확하게 업데이트할 수 있다.
  3. 로드 상태 처리: 로딩, 성공, 실패 상태를 개별적으로 관리하기 쉬워, 복잡한 UI 상태를 제어할 때 적합하다.

단점

  1. 복잡한 코드: 비동기 작업과 상태 관리를 모두 다뤄야 하기 때문에 코드가 복잡해질 수 있다.
  2. 메모리 누수 위험: 비동기 작업이 완료되기 전에 위젯이 소멸되면 메모리 누수가 발생할 가능성이 있다.

2. Stateless 위젯에서 FutureBuilder 사용

Stateless 위젯에서는 FutureBuilder를 사용하여 비동기 데이터를 가져온다. FutureBuilder는 비동기 작업의 완료 상태에 따라 UI를 자동으로 업데이트한다.

예제 코드

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void main() => runApp(MyApp());

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

class FutureDataFetch extends StatelessWidget {
  Future<String> fetchData() async {
    final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
    if (response.statusCode == 200) {
      return jsonDecode(response.body)['title'];
    } else {
      throw Exception('Failed to load data');
    }
  }

  
  Widget build(BuildContext context) {
    return FutureBuilder<String>(
      future: fetchData(),
      builder: (context, snapshot) {
        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(snapshot.data!));
        } else {
          return Center(child: Text('No data found'));
        }
      },
    );
  }
}

Stateless 위젯에서 FutureBuilder 사용의 특징

  • 자동 상태 관리: FutureBuilder는 비동기 작업의 상태 변화를 자동으로 감지하여 적절한 UI를 보여준다.
  • 단순한 구조: 별도의 상태 관리가 필요 없고, 비동기 작업과 UI 업데이트가 한 곳에 집중되어 코드가 간결하다.

장점

  1. 간결함: 비동기 작업과 UI 로직이 한 곳에 집중되어 있어 코드가 간단하고 직관적이다.
  2. 자동 업데이트: 비동기 작업이 완료되면 FutureBuilder가 자동으로 UI를 다시 빌드해준다.
  3. 메모리 관리: 위젯이 소멸되면 FutureBuilder도 함께 종료되기 때문에 메모리 누수의 위험이 적다.

단점

  1. 재빌드 문제: 부모 위젯이 재빌드될 때마다 FutureBuilder도 재실행될 수 있어, 같은 데이터를 반복적으로 요청하게 될 수 있다.
  2. 유연성 부족: 복잡한 상태 관리나 여러 비동기 작업이 필요한 경우에는 제한적일 수 있다.

비교: Stateful async/await vs. Stateless FutureBuilder

특징Stateful 위젯 + async/awaitStateless 위젯 + FutureBuilder
상태 관리setState를 통해 명확하게 관리 가능자동으로 상태 업데이트
코드 가독성코드가 복잡해질 수 있음간결하고 직관적인 코드
복잡한 작업복잡한 비동기 작업과 상태 관리에 유리단순한 비동기 작업에 적합
메모리 관리잘못된 비동기 처리가 메모리 누수 가능성 증가메모리 누수 위험이 적음
UI 재빌드setState 호출 시에만 재빌드부모 위젯이 재빌드될 때마다 Future가 재실행될 수 있음

언제 어떤 방법을 선택해야 할까?

  • Stateful 위젯 + async/await는 복잡한 상태 관리가 필요하거나 여러 개의 비동기 작업을 수행할 때 유리하다.

  • 네트워크 호출과 같은 긴 비동기 작업을 수행할 때도 좋다.

  • 로딩, 성공, 오류 상태를 개별적으로 제어하고 싶을 때 적합하다.

  • Stateless 위젯 + FutureBuilder는 간단한 비동기 작업을 처리하고 싶을 때 적합하다.

  • 상태 관리가 필요 없고, 데이터가 한 번 로드된 후 변경되지 않는 경우에 유리하다.

  • 비동기 작업과 UI가 단순한 경우 코드가 훨씬 간결하다.

결론적으로, 간단한 비동기 작업에는 FutureBuilder를 사용하는 것이 좋고, 복잡한 상태 관리나 비동기 작업을 수행할 때는 Stateful 위젯에서 async/await를 사용하는 것이 더 나은 선택이다.

0개의 댓글