공log/[Flutter]

[Flutter] 플러터 #18 - FutureProvider

ming_OoO 2023. 5. 26. 17:02
728x90

 비동기 작업처리후 결과를 공유하는 FutueProvider에 대해 알아보겠습니다. 

 FutureProvider는 Riverpod 패키지에서 제공하는 프로바이더 중 하나로, 비동기 작업을 처리하고 그 결과를 다른 위젯들과 공유하는 데 사용됩니다. 비동기 작업은 시간이 오래 걸리는 네트워크 요청, 파일 로딩, 데이터베이스 조회 등과 같은 작업을 말합니다. FutureProvider는 이러한 비동기 작업을 효율적으로 관리하고, UI에 필요한 데이터를 제공하는 데 도움이 됩니다.

 

FutureProvider의 사용법은 다음과 같습니다:

  1. FutureProvider를 생성합니다. 예를 들어, FutureProvider<List<int>>를 생성하여 비동기 작업의 결과로 List<int> 데이터를 제공하는 프로바이더를 생성할 수 있습니다.
  2. FutureProvider의 생성자에는 비동기 작업을 정의하는 함수를 전달합니다. 이 함수는 WidgetRef 인스턴스를 매개변수로 받아서 사용됩니다. 비동기 작업은 async 키워드와 await 키워드를 사용하여 처리할 수 있습니다. 작업이 완료되면 결과를 반환합니다.
  3. FutureProvider를 사용하려는 위젯에서 ConsumerWidget을 상속합니다. build 메서드의 매개변수로 BuildContext와 WidgetRef를 받게 됩니다.
  4. WidgetRef의 watch 메서드를 사용하여 FutureProvider의 상태를 감시합니다. 이를 통해 비동기 작업의 진행 상태와 결과를 확인할 수 있습니다.
  5. state.when 메서드를 사용하여 상태에 따라 다른 위젯을 반환하거나 작업 결과를 처리할 수 있습니다. 일반적으로 data, error, loading과 같은 케이스를 사용하여 각각의 상태에 대한 처리 로직을 작성합니다.

 

그렇다면 비동기 작업의 필요성은 무엇일까요?

 비동기 작업의 필요성은 앱에서 사용자 경험을 향상시키기 위해 중요합니다. 예를 들어, 네트워크 요청 결과를 기다리는 동안 사용자에게 로딩 인디케이터를 표시하거나, 데이터가 로드되지 않은 경우에는 기본값을 표시할 수 있습니다. 비동기 작업을 효율적으로 처리하기 위해 FutureProvider를 사용할 수 있습니다.

 FutureProvider는 비동기 작업의 실행 상태를 관리하고, 작업이 완료되면 결과를 다른 위젯들과 공유합니다. 이를 통해 비동기 작업을 보다 쉽게 처리하고, UI에서 필요한 데이터를 표시하고 조작할 수 있습니다. FutureProvider를 사용하면 작업의 진행 상태, 완료 여부, 결과 데이터 등을 관리할 수 있으며, 다양한 UI 로직을 쉽게 구현할 수 있습니다.

 

FutureProviderScreen 위젯과 multiplesFutureProvider 프로바이더의 예제코드를 살펴보겠습니다.

import 'package:flutter_riverpod/flutter_riverpod.dart';

// future provider을 잘 쓰지는 않는다.. 
final multiplesFutureProvider = FutureProvider<List<int>>((ref) async {
  await Future.delayed(
    Duration(
      seconds: 2,
    ),
  );

  // 에러 발생시 화면을 위한 예제 콩드
  // throw Exception('예외입니다.');

  return [1, 2, 3, 4, 5];
});

 multiplesFutureProviderFutureProvider를 사용하여 비동기 작업을 수행합니다. 이 프로바이더는 2초의 딜레이 후에 [1, 2, 3, 4, 5]라는 데이터를 반환합니다. 주석 처리된 부분에서는 에러를 강제로 발생시켜 예외 상황을 시뮬레이션할 수도 있습니다.

 

다음은 FutureProviderScreen의 코드입니다.

class FutureProviderScreen extends ConsumerWidget {
  const FutureProviderScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // FutureProvider <- 자동으로 캐싱이 된다.
    final state = ref.watch(multiplesFutureProvider);

    return DefaultLayout(
      title: 'FutureProviderScreen',
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          state.when(
            // 각각이 다 함수
            // data: 로딩이 된 후 data가 있을 때
            // error: error가 있을 때
            // loading: loading 중일 떄
            data: (data) {
              return Text(
                data.toString(),
                textAlign: TextAlign.center,
              );
            },
            error: (err, stack) => Text(
              err.toString(),
            ),
            loading: () => Center(
              child: CircularProgressIndicator(),
            ),
          ),
        ],
      ),
    );
  }
}

FutureProviderScreen 위젯에서는 ConsumerWidget을 상속하고, ref.watch를 사용하여 multiplesFutureProvider의 상태를 감시합니다. stateref.watch(multiplesFutureProvider)의 결과로 반환된 상태 객체입니다.

 state.when 메서드는 state의 상태에 따라 다른 위젯을 반환합니다. data 케이스에서는 비동기 작업의 결과인 데이터를 텍스트로 출력합니다. error 케이스에서는 에러 메시지를 텍스트로 출력합니다. loading 케이스에서는 로딩 중임을 나타내는 인디케이터를 표시합니다.

 이를 통해 FutureProvider를 사용하여 비동기 작업의 실행 상태를 관리하고, 결과를 화면에 표시할 수 있습니다. 실행 결과에 따라 데이터, 에러 메시지, 로딩 인디케이터를 보여줌으로써 사용자에게 직관적인 경험을 제공할 수 있습니다.

 

실행결과입니다.

 마지막으로 FutureProvider의 장점과 Riverpod의 유용성에 대해 알아보겠습니다.

FutureProvider의 장점:

  1. 간편한 비동기 작업 관리: FutureProvider를 사용하면 비동기 작업의 실행 상태와 결과를 편리하게 관리할 수 있습니다. FutureProvider는 작업의 진행 상태를 추적하고, 작업이 완료되면 결과를 제공합니다.
  2. 데이터 공유: FutureProvider는 비동기 작업의 결과를 다른 위젯들과 공유할 수 있습니다. 한 번의 비동기 호출로 여러 위젯에서 동일한 데이터에 접근할 수 있으며, 데이터 변경 시 자동으로 업데이트됩니다.
  3. 자동 캐싱: FutureProvider는 자동으로 비동기 작업의 결과를 캐싱합니다. 이는 동일한 작업을 여러 번 호출할 때 유용하며, 중복된 작업을 효율적으로 처리할 수 있습니다.

Riverpod의 유용성:

  1. 의존성 관리: Riverpod은 의존성 주입(Dependency Injection)을 위한 강력한 도구입니다. Provider를 통해 앱 전반에서 데이터와 상태를 효율적으로 공유하고, 의존성을 관리할 수 있습니다.
  2. 상태 관리: Riverpod은 상태 관리에 용이한 방법을 제공합니다. Provider를 사용하여 상태를 공유하고, 상태의 변경을 감지하여 UI를 업데이트할 수 있습니다. 상태 변화를 추적하고 리액트형(React-style)으로 UI를 업데이트하는 것이 간단하고 직관적입니다.
  3. 유연성과 확장성: Riverpod은 강력하고 유연한 기능을 제공하며, 다양한 앱 아키텍처 패턴과 통합이 가능합니다. 상태 관리, 비동기 작업 처리, 의존성 주입 등을 모두 Riverpod을 통해 효율적으로 관리할 수 있습니다.

이러한 FutureProvider와 Riverpod은 플러터 앱 개발을 더욱 효율적으로 만들어주고, 코드의 가독성과 유지 보수성을 향상시킬 수 있습니다. Riverpod을 사용하면 앱의 확장성과 유연성이 향상되며, 개발자는 보다 직관적이고 효율적인 방식으로 앱을 구축할 수 있습니다.

728x90