Study/Development

[개발일지] Flutter Bloc 상태관리 #3 GetX vs Cubit vs Bloc

titann 2023. 4. 8. 17:00

 

Flutter BlocFlutter Bloc 상태관리 #3 GetX vs Cubit vs Bloc

<인프런 개발하는 남자 온라인강의 수강일지>


GetX vs Cubit vs Bloc

GetX

  • 여러개 상태를 한번에 관리
  • GetX를 사용하더라도 쪼개서 사용하면 유지 보수, 코드 재사용이 용이

Cubit 구조

  • cubit과 bloc은 하나만 존재.
  • 상태와 타입을 하나만
  • emit 함수를 이용하여 상태 변경, cubit이나 bloc에서만 사용 가능

Bloc 구조

  • GetX나 Cubit에 비해 번거로움
  • Bloc, Event, State가 구분되어있다.
  • 디테일하게 이벤트 트래킹이 가능하다.

GetX

1. View Page


// GetX Page는 GetView를 extends 해준다.
class GetxHome extends GetView<CountGetxController> {
  const GetxHome({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('GetX 상태관리'),
      ),
      body: Center(
		// 상태 변화가 필요한 곳은 Obx로 감싸준다.
        child: Obx(
          () => Text(
            controller.count.value.toString(),
            style: TextStyle(fontSize: 80),
          ),
        ),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          FloatingActionButton(
			// controller.함수명으로 함수 실행
            onPressed: controller.addCount,
            backgroundColor: Colors.blue,
            child: Icon(Icons.add),
          ),
          const SizedBox(width: 30),
          FloatingActionButton(
			// controller.함수명으로 함수 실행
            onPressed: controller.substractCount,
            backgroundColor: Colors.red,
            child: Icon(Icons.remove),
          ),
        ],
      ),
    );
  }
}

2.GetX Controller


// GetX import
import 'package:get/get.dart';

// GetxController extends
class CountGetxController extends GetxController {
  RxInt count = 0.obs;

// 함수1
  void addCount() {
    count(count.value + 1);
  }

// 함수2
  void substractCount() {
    count(count.value - 1);
  }
}

Cubit

1. View Page


import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_bloc_01/src/cubit/count_cubit.dart';

class CubitHome extends StatelessWidget {
  const CubitHome({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Cubit 상태관리'),
      ),
      body: Center(
		// BlocBuilder로 감싸준다.
		// <> 안에는 cubit, state가 들어간다.
        child: BlocBuilder<CountCubit, int>(
			// Builder Option에서 state를 받아온다.
          builder: (context, state) {
            return Text(
              state.toString(),
              style: TextStyle(fontSize: 80),
            );
          },
        ),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          FloatingActionButton(
			// context.read<>().함수명 으로 함수 호출
            onPressed: context.read<CountCubit>().addCount,
            backgroundColor: Colors.blue,
            child: Icon(Icons.add),
          ),
          const SizedBox(width: 30),
          FloatingActionButton(
			// context.read<>().함수명 으로 함수 호출
            onPressed: context.read<CountCubit>().substractCount,
            backgroundColor: Colors.red,
            child: Icon(Icons.remove),
          ),
        ],
      ),
    );
  }
}

2. count_cubit.dart


import 'package:bloc/bloc.dart';

// <> 안에 상태 Class를 지정한다.
class CountCubit extends Cubit<int> {
	// 최초 State를 0으로 설정
  CountCubit() : super(0);

	// emit을 통해 현재 State를 반환
  void addCount() {
    emit(state + 1);
  }

  void substractCount() {
    emit(state - 1);
  }
}

Bloc

1. View Page


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

class BlocHome extends StatelessWidget {
  const BlocHome({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Bloc 상태관리'),
      ),
      body: Center(
		// BlocBuilder <>안에는 bloc, state class
        child: BlocBuilder<CountBloc, int>(builder: (context, state) {
          return Text(
            state.toString(),
            style: TextStyle(fontSize: 80),
          );
        }),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          FloatingActionButton(
			// onPressed안에 context.read<>.add(상태 이벤트 클래스)로 상태 변경해준다.
            onPressed: () {
              context.read<CountBloc>().add(AddCountEvent());
            },
            backgroundColor: Colors.blue,
            child: Icon(Icons.add),
          ),
          const SizedBox(width: 30),
          FloatingActionButton(
            onPressed: () {
              context.read<CountBloc>().add(SubstractCountEvent());
            },
            backgroundColor: Colors.red,
            child: Icon(Icons.remove),
          ),
        ],
      ),
    );
  }
}

2. count_bloc.dart


import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';

// Bloc Class, Bloc<Event, State>로 extends해준다.
class CountBloc extends Bloc<CountEvent, int> {
  CountBloc() : super(0) {
    on<AddCountEvent>((event, emit) {
      emit(state + 1);
    });
    on<SubstractCountEvent>((event, emit) {
      emit(state - 1);
    });
  }
}

// abstract class로 Event Class를 따로 선언해준다.
abstract class CountEvent extends Equatable {}

class AddCountEvent extends CountEvent {
  @override
  List<Object?> get props => [];
}

class SubstractCountEvent extends CountEvent {
  @override
  List<Object?> get props => [];
}
반응형