Study/Dart,Flutter

8. Dart, Flutter 상태관리 그리고 Riverpod (1)

코딩 잘 할거얌:) 2021. 10. 28. 23:18
반응형

이번 포스팅은 상태 관리법 중 하나인 Riverpod 알아보도록 하자.

이론적인 내용이므로 만약 코드에 바로 사용할 방법을 찾는다면 다음 포스팅을 읽으면 된다.

 

이렇게 이해하더라도 한 번은 꼭 읽어보자 (대학일기)

목차

  1. Flutter의 상태관리
    1. Flutter의 상태 관리 
    2. Ephemeral state와 App state
    3. Riverpod과 Provider의 차이점

1. Flutter의 상태관리

Flutter의 상태 관리란, 데이터의 상태라고 생각해도 좋다. 현재 데이터에 맞게 화면을 변경해주고 유저의 반응에 대응해주기 위해서 필요하다. 하지만 모든 데이터를 관리해야 하나 그것은 아니다. 어떤 상태(데이터)이냐에 따라 Ephemeral(일시적) state, App state로 나뉘게 된다. 공식문서 링크는 아래를 참고하면 된다.

https://flutter.dev/docs/development/data-and-backend/state-mgmt/ephemeral-vs-app

 

Differentiate between ephemeral state and app state

How to tell the difference between ephemeral and app state.

flutter.dev

1.Ephemeral state와 App state

Ephemeral state는 임시적인 상태라는 뜻이다. Local state와 의미가 같다. Local state는 조금 더 이해하기가 쉽다. 한 개의 위젯이 가지는 상태를 Ephemeral state라고 한다. 가령,

  • 현재 PageView
  • 현재 진행 중인 애니메이션
  • BottomNavigationBard의 현재 탭

을 일컫는다. 이러한 경우에는 상태 관리법을 사용하는 게 필요 없다. 조금 더 단순하게 생각을 하자면, 현재 페이지에서만 사용하는 상태이며, 다른 곳에서는 영향을 주지 않는 경우(Local)를 말한다. 그래서 이러한 경우에는 상태 관리가 크게 필요하지 않다.

하지만 앱 전체에 영향을 주는 경우에는 상태 관리를 해야 한다는 뜻이다.

 

2. App state

App state는 어떠한 상태가 앱 전체에 영향을 주는 경우를 말한다. 예를 들어,

  • 로그인 정보
  • 유저의 설정
  • 쿠팡의 장바구니
  • 인스타그램 혹은 페이스북의 알림
  • 네이버 혹은 구글의 메일 읽음과 읽지 않음 처리

이러한 경우에는 앱 전체에 영향을 주기 때문에 App state라고 한다. shared state라고도 한다. 따라서 상태 관리를 필요로 한다.

그렇다면 이 두 상태의 명확한 구분이 있을까?

 

없다.

개발을 할 때 처음에는 Ephemeral state라고 생각을 했었지만, 리팩터링 하며 App state로 변경하는 경우가 생긴다. 따라서 명확하게 구분하는 방법은 없다.

Dan Abramov분은, '최고의 규칙은 덜 어색한 것이다.'라고 하였다.

이러한 App state를 관리하는 것이 state management이다 상태 관리법. 상태관리법 중 Riverpod에 대해서 알아보자.

 

3. Riverpod과 Provider의 차이점

Riverpod은 Provider의 단점들을 개선한 버전이다. 우선 Riverpod 공식 사이트에서 이야기하는 장점을 살펴보도록 하자

깨알같은 내용 : Provider에서 파생된 Riverpod은 Provider의 언어유희에서 나온 말이다. Provider에서  P, O, D를 뒤로보내면 riverPOD이 된다.

https://riverpod.dev/

 

Riverpod

A boilerplate-free and safe way to share state

riverpod.dev

 

  • Riverpod은 컴파일 타임 동안 안전하다.
  • Flutter SDK에 직접적으로 의존하지 않는다.
  • Provider의 제한사항이 없다.
  • 어디서든 명시된 상태를 공유한다.
  • 상태 또는 UI rebuild를 필요할 때만 한다.
  • Riverpod은 loading/error 케이스를 깔끔하게 다룰 수 있다.
  • devtool로 상태를 검사할 수 있다.

나는 Provider를 사용하다가 Riverpod으로 전향했다. 바꾼 큰 이유는 두 가지이다.

3.1 Provider에서 동일한 타입 선언

Provider에서 MultiProvider는 동일한 타입을 사용할 수 없다. 예를 들어 

StreamProvider<List<CakeDataCalendarPickUp>>.value(
  value: db.getCalendarPickUpCakeData(),
  catchError: (context, error) {
    print(error);
    return null;
  },
),

이렇게 StreamProvider에 명시적으로 데이터 타입을 적어줘야 하는데, 만약 또 다른 SteramProvider를 만들어서 데이터 타입을 List<<CakeDataCalendarPickUp>>만들어야 한다면, CakeDataCalendarPickUp을 상속을 받던 해서 다른 이름으로 만들어야 한다. 하지만 Riverpod에서는 그러한 제약사항이 존재하지 않는다.

final cakePriceProvider =
    ChangeNotifierProvider<CakePriceProvider>((ref) => CakePriceProvider());

Riverpod에서는 이렇게 선언을 하더라도 cakePriceProvider의 이름만 다르게 하면 될 뿐, 동일한 타입이어도 상관이 없다.

 

3.2 어디에서든 명시를 할 수 있다.

Provider는 main에서 선언을 해야 한다. 예를 들어

MultiProvider(
  providers: [
    Provider<Something>(create: (_) => Something()),
    Provider<SomethingElse>(create: (_) => SomethingElse()),
    Provider<AnotherThing>(create: (_) => AnotherThing()),
  ],
  child: someWidget,
)

이렇게 메인에서 MultiProvider를 적어야 한다. 물론 한 곳에서 모아서 볼 수 있다는 장점이 있겠지만, 내가 원하는 곳에 명시할 수 없다는 점이 단점이라고 생각한다. 반면 Riverpod의 경우에는 전역 변수처럼 선언을 하면 된다.

//전역변수처럼 선언하면 된다.
final partTimerProvider =
    ChangeNotifierProvider<PartTimerProvider>((ref) => PartTimerProvider());

class name extends StatefulWidget {
  name({Key? key}) : super(key: key);

  @override
  _nameState createState() => _nameState();
}

class _nameState extends State<name> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

 


 

 

요약하자면, 

  1. Flutter의 상태는 Ephemeral state와 App state 두 가지가있다.
  2. Ephemeral state는 앱 단편적으로 사용하는 상태, App state는 앱 전체에 영향을 주는 상태이다.
  3. App state를 관리하는 것이 상태관리이고, 상태관리법에는 Bloc, provider, Riverpod, getX 등이 있다.
  4. riverpod은 provider의 단점을 보완하기 위하여 나온것으로 provider의 연장선이라고 생각해도 된다.

여기까지 Flutter의 상태 관리 중 하나인 Riverpod에 대해서 알아보았다. 다음에는 Riverpod을 사용하는 법 그리고 Firebase와 연동하는 법을 포스팅하도록 하겠다.

728x90