[flutter] 플러터 Riverpod를 이용한 앱 아키텍처 설계 방법

플러터는 크로스 플랫폼 앱 개발을 위한 강력하고 유연한 프레임워크입니다. Riverpod는 플러터 앱의 상태 관리와 의존성 주입을 쉽게 할 수 있도록 도와주는 라이브러리입니다. 이번 글에서는 Riverpod를 이용하여 플러터 앱의 아키텍처를 어떻게 설계할 수 있는지 살펴보겠습니다.

1. Riverpod 소개

Riverpod는 Provider 패턴을 기반으로 한 플러터 앱의 아키텍처를 관리하는 라이브러리입니다. Provider 패턴은 의존성 주입을 통해 앱의 상태를 관리하고, 위젯들 간의 데이터 공유를 용이하게 해줍니다. Riverpod는 Provider 패턴을 더욱 간결하고 효율적으로 사용할 수 있도록 도와줍니다.

2. Riverpod 설치

Riverpod를 사용하기 위해서는 먼저 해당 라이브러리를 설치해야 합니다. pubspec.yaml 파일에 다음과 같이 의존성을 추가합니다:

dependencies:
  flutter_riverpod: ^1.0.0

의존성을 추가한 후에는 flutter pub get 명령을 실행하여 라이브러리를 다운로드 받습니다.

3. Riverpod를 이용한 앱 아키텍처 설계 방법

Riverpod를 이용한 앱 아키텍처 설계는 크게 3가지 단계로 나눌 수 있습니다.

3.1 Provider 생성

먼저, 앱의 상태를 관리하는 Provider를 생성해야 합니다. Provider는 Provider 또는 Consumer를 이용하여 생성할 수 있으며, ProviderScope 내부에서 사용됩니다.

다음은 CounterProvider라는 Provider를 생성하는 예제입니다:

import 'package:flutter_riverpod/flutter_riverpod.dart';

final counterProvider = Provider<int>((ref) {
  return 0;
});

위 예제에서 Provider<int>는 정수(int) 타입의 상태를 관리하는 Provider를 생성한다는 의미입니다. (ref)는 Provider 내부에서 의존성 주입을 위해 사용되는 Reference를 의미합니다.

3.2 Provider 사용

Provider를 생성한 후에는 해당 Provider를 사용하여 상태를 관리하는 위젯과 데이터를 공유하는 위젯들을 작성할 수 있습니다.

다음은 CounterProvider를 사용하여 상태를 관리하고, 이를 화면에 표시하는 예제입니다:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() {
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Riverpod Example',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Counter App'),
        ),
        body: Center(
          child: Consumer(
            builder: (context, watch, _) {
              final count = watch(counterProvider);
              return Text('Count: $count');
            },
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            context.read(counterProvider).state++;
          },
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

위 예제에서 ProviderScope는 Provider의 스코프를 지정하기 위해 사용되는 위젯입니다. Consumer 위젯은 Provider로부터 데이터를 읽어와 화면에 표시하는 위젯입니다. watch(counterProvider)는 CounterProvider의 상태를 읽어오는 역할을 합니다. 마지막으로, context.read(counterProvider).state++는 CounterProvider의 값을 증가시키는 역할을 합니다.

3.3 Provider 갱신

Provider를 갱신하는 방법은 다양합니다. 가장 기본적인 방법은 ProviderContainer를 이용하여 Provider의 값을 변경하는 것입니다.

다음은 CounterProvider를 갱신하는 예제입니다:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() {
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Riverpod Example',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Counter App'),
        ),
        body: Center(
          child: Consumer(
            builder: (context, watch, _) {
              final count = watch(counterProvider);
              return Text('Count: $count');
            },
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            context.read(counterProvider).state++;
          },
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

위 예제에서 context.read(counterProvider).state++는 CounterProvider의 값을 증가시키는 역할을 합니다. 이렇게 Provider의 값을 변경하면, 관련된 위젯들이 자동으로 다시 렌더링되어 화면이 갱신됩니다.

4. 마무리

이렇게 Riverpod를 이용하여 플러터 앱의 아키텍처를 설계하는 방법에 대해 알아보았습니다. Riverpod를 사용하면 상태 관리와 의존성 주입을 효율적으로 처리할 수 있으며, 앱의 확장과 유지보수를 더욱 쉽게 할 수 있습니다. Riverpod에 대해 더 자세히 알고 싶다면, 공식 문서를 참고해보세요.

Happy coding!