Cubit

하요·2024년 7월 8일
0

Flutter State Management

목록 보기
6/7
post-thumbnail

Flutter에서 BLoC의 간소화: Cubit

Cubit은 BLoC 패턴을 간소화한 버전입니다. BLoC에서는 상태(State)와 이벤트(Event)를 각각 정의하고 관리해야 하지만, Cubit은 상태(State) 클래스만 구현하고, 메서드를 통해 이벤트를 처리합니다. 이를 통해 코드의 복잡성을 줄이고 더 간단하게 상태 관리를 할 수 있습니다.

BLoC 패턴

BLoC(Business Logic Component) 패턴은 애플리케이션을 다음과 같은 구성 요소로 나누어 관리합니다:

  • View: 사용자 인터페이스(UI)와 관련된 부분.
  • State: 현재 상태를 나타내는 객체.
  • Event: 상태를 변경하는 이벤트.
  • Data: 애플리케이션의 데이터.

BLoC 패턴은 Stream을 이용하여 상태와 이벤트를 송수신하며, 이를 통해 View와 비즈니스 로직을 분리하여 구조적으로 관리합니다.

주요 개념

  • Cubit 클래스: 상태를 관리하는 기본 클래스입니다. Cubit<상태 타입>을 상속받아 커스텀 Cubit을 생성하고, 상태 변경 로직을 정의합니다.
  • 상태(States): Cubit의 상태는 단순한 Dart 객체입니다. 상태가 변경될 때마다 새로운 객체로 대체되어 UI가 업데이트됩니다.
  • 상태 전환(Emit): emit 메서드를 통해 새로운 상태로 전환합니다. 상태가 전환되면 이를 구독하고 있는 UI 컴포넌트들이 자동으로 업데이트됩니다.

주요 속성 및 메서드

  • state: 현재 상태를 나타냅니다.
  • emit(newState): 새로운 상태로 전환합니다.
  • Cubit 생성자: 초기 상태를 설정합니다.

주요 활용도

  • 상태 전환 간소화: 이벤트 클래스를 생성할 필요 없이 메서드를 통해 직접 상태 전환을 관리할 수 있습니다.
  • UI 업데이트 자동화: 상태가 전환될 때 UI가 자동으로 업데이트됩니다.
  • 다양한 상태 관리: 단일 Cubit 클래스에서 여러 상태를 관리할 수 있습니다.

코드 예제

아래 예제는 Cubit을 사용하여 카운터를 증가시키고 감소시키는 방법을 보여줍니다.

import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

// Cubit 클래스 정의
class CounterCubit extends Cubit<int> {
  CounterCubit() : super(0); // 초기 상태는 0

  void increment() => emit(state + 1); // 상태 증가
  void decrement() => emit(state - 1); // 상태 감소
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BlocProvider(
        create: (_) => CounterCubit(),
        child: CounterPage(),
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    final counterCubit = context.read<CounterCubit>();

    return Scaffold(
      appBar: AppBar(title: Text('Cubit Counter Example')),
      body: Center(
        child: BlocBuilder<CounterCubit, int>(
          builder: (context, count) {
            return Text('$count', style: TextStyle(fontSize: 24));
          },
        ),
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          FloatingActionButton(
            child: Icon(Icons.add),
            onPressed: () => counterCubit.increment(),
          ),
          SizedBox(height: 8),
          FloatingActionButton(
            child: Icon(Icons.remove),
            onPressed: () => counterCubit.decrement(),
          ),
        ],
      ),
    );
  }
}

Cubit의 접근 방법

  • context.watch(): 상태가 변경될 때마다 위젯을 갱신합니다.
  • context.read(): 상태가 변경되어도 위젯을 갱신하지 않습니다.
  • BlocBuilder: 특정 위젯만 갱신합니다. buildWhen을 사용하여 갱신 여부를 결정할 수 있습니다.

Cubit 제공자 종류

  • BlocProvider: 상태 변경 알림 기능이 있는 Cubit을 위젯 트리에 등록할 때 사용합니다.
  • RepositoryProvider: 상태 변경 알림 기능이 없는 클래스를 위젯 트리에 등록할 때 사용합니다.

Cubit 상호 작용 및 주의사항

Cubit 간의 상태 변경을 동기화하려면 StreamSubscription을 사용하여 다른 Cubit의 상태 변화를 수신하고, 이를 바탕으로 상태를 업데이트합니다. 이를 통해 여러 Cubit 간의 상호 작용을 구현할 수 있습니다.

주의사항

StreamSubscription을 사용한 경우, 반드시 구독을 해제해야 메모리 누수를 방지할 수 있습니다. 이를 위해 close 메서드를 호출하여 Cubit이 더 이상 필요 없을 때 구독을 해제해야 합니다.

class ExampleCubit extends Cubit<ExampleState> {
  final AnotherCubit anotherCubit;
  late StreamSubscription anotherCubitSubscription;

  ExampleCubit(this.anotherCubit) : super(InitialExampleState()) {
    anotherCubitSubscription = anotherCubit.stream.listen((state) {
      // Handle state changes
    });
  }

  
  Future<void> close() {
    anotherCubitSubscription.cancel();
    return super.close();
  }
}

상태 클래스 관리

하나의 Cubit 클래스에서 여러 상태를 관리하려면 상태 클래스를 불변 객체로 생성합니다. copyWith 메서드를 사용하여 불변 객체의 특정 속성만 변경하고, 새로운 객체를 생성하여 상태를 전환합니다.

추가 팁

  • 복잡한 상태 관리: 단순한 상태 관리에는 Cubit이 적합하지만, 보다 복잡한 상태 관리가 필요한 경우에는 BLoC 패턴을 사용하는 것이 더 적합할 수 있습니다.
  • 반응형 디자인: 다양한 기기와 화면 크기에 대응하기 위해 반응형 디자인을 고려하는 것이 중요합니다.

관련 자료

profile
flutter 개발자(진)

0개의 댓글