티스토리 뷰

개발

flutter Riverpod 사용법

코지식 2024. 10. 24. 00:04

목차



    반응형

     

    플러터(Flutter)로 앱을 개발할 때 상태 관리는 필수적인 요소입니다. 다양한 상태 관리 도구들이 있지만, 그 중에서 Riverpod는 타입 안전성과 강력한 의존성 주입 기능을 제공하는 도구로 각광받고 있습니다. 이 블로그에서는 Riverpod에 대해 간단히 설명하고, 예제 코드를 통해 사용 방법을 이해하기 쉽게 설명하겠습니다.

     

    Riverpod란?

    Riverpod는 Flutter의 상태 관리 라이브러리입니다. Riverpod는 플러그인 없이도 다른 Dart 프로젝트에서도 사용할 수 있어 매우 유연하며, 특히 복잡한 의존성 관리나 상태 공유를 쉽게 처리할 수 있도록 돕습니다.

    Riverpod의 주요 특징

    • 타입 안전성: 모든 상태와 제공되는 값들은 타입 체크가 이루어져 개발 중 오류를 미리 방지할 수 있습니다.
    • 의존성 주입: Riverpod는 의존성 관리가 쉬워 다른 상태와 값들을 자연스럽게 주입할 수 있습니다.
    • 간결한 API: 관리가 복잡한 상태를 처리할 때, 간결한 API로 쉽게 상태를 업데이트하고 추적할 수 있습니다.

    Riverpod 시작하기

     

     

    1. Riverpod 설치

    먼저, pubspec.yaml 파일에 Riverpod 패키지를 추가해야 합니다.

    dependencies:
      flutter:
        sdk: flutter
      flutter_riverpod: ^2.0.0 # 최신 버전으로 설정

     

    그 후, 패키지를 설치합니다.

    flutter pub get

     

    2. 간단한 Riverpod 예제

    이제 간단한 상태 관리를 구현한 예제를 살펴보겠습니다. 이 예제에서는 숫자를 증가시키는 간단한 카운터 애플리케이션을 만듭니다.

     

     

     

    Step 1: Provider 정의

    먼저, 상태를 관리할 Provider를 정의합니다. Provider는 상태를 생성하고, 다른 위젯에서 이를 구독할 수 있도록 해주는 역할을 합니다.

    import 'package:flutter_riverpod/flutter_riverpod.dart';
    
    // Provider로 관리할 상태의 기본 값 설정 (0부터 시작하는 카운터)
    final counterProvider = StateProvider<int>((ref) => 0);

     

    Step 2: Riverpod을 사용하는 Flutter 앱 구현

    이제 Flutter 앱에 Riverpod을 적용해보겠습니다.

    import 'package:flutter/material.dart';
    import 'package:flutter_riverpod/flutter_riverpod.dart';
    
    // 앱의 진입점
    void main() {
      runApp(ProviderScope(child: MyApp()));
    }
    
    // Riverpod을 사용하는 기본 Flutter 위젯
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: HomeScreen(),
        );
      }
    }
    
    // 상태를 관리하고 UI에 적용하는 화면
    class HomeScreen extends ConsumerWidget {
      @override
      Widget build(BuildContext context, WidgetRef ref) {
        // provider로부터 현재 카운터 상태를 구독
        final counter = ref.watch(counterProvider);
    
        return Scaffold(
          appBar: AppBar(
            title: Text('Riverpod Counter Example'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  'You have pushed the button this many times:',
                ),
                // 상태를 화면에 표시
                Text(
                  '$counter',
                  style: Theme.of(context).textTheme.headline4,
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              // 상태를 업데이트 (카운터 증가)
              ref.read(counterProvider.notifier).state++;
            },
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    }

     

     

     

    Step 3: 코드 설명

    • ProviderScope: main() 함수에서 ProviderScope로 감싸는 것은 Riverpod 상태 관리의 기본 설정입니다. 이 안에 있는 모든 위젯은 Provider에 접근할 수 있습니다.
    • StateProvider: counterProvider는 상태가 변경될 때 UI를 업데이트하기 위해 사용되는 상태 관리 객체입니다. 여기서는 int형의 카운터 상태를 관리합니다.
    • ConsumerWidget: ConsumerWidget은 Provider에서 관리하는 상태를 구독하고 UI에서 사용할 수 있게 해줍니다. WidgetRef를 통해 상태를 읽고 구독할 수 있습니다.
    • ref.read(): Provider의 상태를 직접 수정할 때 사용됩니다. 이 예제에서는 ref.read(counterProvider.notifier).state++를 통해 카운터 값을 증가시킵니다.
    • ref.watch(): Provider에서 제공하는 상태를 구독하여 UI를 업데이트할 때 사용됩니다. 이 예제에서는 final counter = ref.watch(counterProvider)를 통해 카운터 값을 구독하고 화면에 표시합니다.

    Riverpod의 활용 사례

     

    1. 비동기 상태 관리

    Riverpod은 비동기 데이터도 쉽게 관리할 수 있습니다. 예를 들어, API 호출 결과를 관리할 때 FutureProvider나 StreamProvider를 사용할 수 있습니다.

    final fetchWeatherProvider = FutureProvider<String>((ref) async {
      // 비동기 API 호출 시뮬레이션
      await Future.delayed(Duration(seconds: 2));
      return "Sunny";
    });

     

    이제 이 데이터를 ref.watch()를 통해 화면에 표시할 수 있습니다.

    class WeatherScreen extends ConsumerWidget {
      @override
      Widget build(BuildContext context, WidgetRef ref) {
        final weatherAsyncValue = ref.watch(fetchWeatherProvider);
    
        return weatherAsyncValue.when(
          data: (weather) => Text('Weather: $weather'),
          loading: () => CircularProgressIndicator(),
          error: (err, stack) => Text('Error: $err'),
        );
      }
    }

     

    2. 의존성 주입

    Riverpod은 서로 의존하는 Provider를 자연스럽게 주입할 수 있습니다. 아래 예제에서는 counterProvider에 의존하는 다른 상태를 정의해보겠습니다.

    final doubleCounterProvider = Provider<int>((ref) {
      final counter = ref.watch(counterProvider);
      return counter * 2;
    });

     

    Riverpod vs Provider

    Flutter에서 가장 널리 사용되는 상태 관리 라이브러리 중 하나인 Provider와 Riverpod는 유사한 부분이 많지만, 몇 가지 주요 차이점이 있습니다.

    특징 Provider Riverpod
    코드 간결성 설정 필요 간결하고 직관적
    타입 안전성 부분적 지원 강력한 타입 지원
    테스트 용이성 상대적으로 어려움 매우 쉽고 직관적
    의존성 주입 가능하지만 불편 매우 쉽고 자연스러움

     

     

    결론

    Riverpod는 Flutter의 상태 관리를 매우 직관적이고 효율적으로 할 수 있게 도와주는 도구입니다. 타입 안전성과 의존성 주입의 편리함 덕분에 유지보수가 쉽고, 코드의 가독성이 높아집니다. 간단한 예제를 통해 상태 관리의 기본 개념을 배웠으니, 이제 더 복잡한 앱에서도 Riverpod을 사용하여 상태 관리를 쉽게 해보세요!

     

     

    반응형