RxDart 패키지를 이용한 BLoC Pattern 예시

Chang Hyun Kim·2021년 3월 5일
0

Flutter BLoC Pattern

목록 보기
2/7

RxDart

ReactiveX API를 Dart에서 사용할 수 있게 구현한 패키지

Stream을 사용하기 용이하게 확장합니다.

RxDart를 이용한 BLoC Pattern 예시

예시코드

int 형태의 count를 state로 가지는 CounterBloc 클래스

초깃값과 해당 Bloc의 상태를 변화하는 함수 등을 정의합니다.

BehaviorSubject 클래스를 통해 데이터 등을 Listener에게 보내줍니다.

class CounterBloc {
  int count = 0;
  BehaviorSubject<int> _subjectCounter;

  CounterBloc({this.count}) {
    _subjectCounter = BehaviorSubject<int>.seeded(this.count);
  }

  Stream<int> get stream => _subjectCounter.stream;

  void increment() {
    count++;
    _subjectCounter.sink.add(count);
  }

  void decrement() {
    count--;
    _subjectCounter.sink.add(count);
  }

  void reset() {
    count = 0;
    _subjectCounter.sink.add(count);
  }

  void dispose() {
    _subjectCounter.close();
  }
}

위젯에서의 사용

  • StreamBuilder로 해당 Bloc의 State를 가져오는 위젯을 생성합니다.

  • CounterBloc 객체를 생성하여 Stream과 함수를 가져옵니다.

  • FutureBuilder 와 마찬가지로 snapshot을 이용해서 데이터를 받아올 수 있습니다.

  • 버튼 클릭 시 상태를 변화하는 함수를 호출하며 State 값이 바뀌게 됩니다.

  • 위젯에서는 해당 비즈니스 로직에 대한 구현을 신경 쓰지 않고 해당 Bloc의 State를 보여주는 부분만 신경 쓰면 된다는 점을 알 수 있습니다.

class CounterScreen extends StatelessWidget {
  
  Widget build(BuildContext context) {
    CounterBloc _counterBloc = new CounterBloc(count: 0);

    return Scaffold(
      appBar: AppBar(title: Text("Counter with RxDart")),
      body: Center(
        child: StreamBuilder(
          stream: _counterBloc.stream,
          builder: (context, snapshot) {
            return Text('${snapshot.data}',
                style: Theme.of(context).textTheme.headline2);
          },
        ),
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
              onPressed: () => _counterBloc.increment(),
              tooltip: "Increment",
              child: Icon(Icons.add)),
          FloatingActionButton(
              onPressed: () => _counterBloc.decrement(),
              tooltip: "Decrement",
              child: Icon(Icons.remove)),
          FloatingActionButton(
              onPressed: () => _counterBloc.reset(),
              tooltip: "Reset",
              child: Icon(Icons.refresh)),
        ],
      ),
    );
  }
}

profile
https://kimbiyam.me/ 블로그 이전하였습니다

0개의 댓글