주요 콘텐츠로 건너뛰기

^0.14.0에서 ^1.0.0

오랜 기다림 끝에 드디어 리버팟의 첫 번째 안정 버전이 출시되었습니다 👏.

전체 변경 목록을 보려면 변경 로그를 참조하세요.
이 페이지에서는 기존 Riverpod 애플리케이션을 버전 0.14.x에서 버전 1.0.0으로 마이그레이션하는 방법에 대해 중점적으로 설명합니다.

마이그레이션 도구를 사용하여 프로젝트를 새 구문으로 자동 업그레이드하기

다양한 변경 사항을 설명하기 전에, Riverpod에는 프로젝트를 자동으로 마이그레이션할 수 있는 명령줄 도구가 함께 제공된다는 점을 알아둘 필요가 있습니다.

명령줄 도구 설치하기

마이그레이션 도구를 설치하려면 다음을 실행합니다:

dart pub global activate riverpod_cli

이제 실행할 수 있을 것입니다:

riverpod --help

사용법

이제 명령줄이 설치되었으므로 사용을 시작할 수 있습니다.

  • 먼저 터미널에서 마이그레이션하려는 프로젝트를 엽니다.

  • Riverpod을 업그레이드하지 마세요. 마이그레이션 도구가 Riverpod의 버전을 업그레이드해 줍니다.

    위험

    Riverpod을 업그레이드하지 않는 것이 중요합니다.
    이미 버전 1.0.0을 설치한 경우 도구가 제대로 실행되지 않습니다. 따라서 도구를 시작하기 전에 이전 버전을 제대로 사용하고 있는지 확인하세요.

  • 프로젝트에 오류가 없는지 확인합니다.

  • 실행:

    riverpod migrate

그러면 도구가 프로젝트를 분석하고 변경 사항을 제안합니다. 예를 들면 다음과 같습니다:

-Widget build(BuildContext context, ScopedReader watch) {
+Widget build(BuildContext context, Widget ref) {
- MyModel state = watch(provider);
+ MyModel state = ref.watch(provider);
}

Accept change (y = yes, n = no [default], A = yes to all, q = quit)?

변경을 수락하려면 Y를 누르면 됩니다. 변경을 거부하려면 n을 누르세요.

변경사항

이제 CLI를 사용하여 프로젝트를 자동으로 업그레이드하는 방법을 살펴봤으니 필요한 변경 사항을 자세히 살펴봅시다.

구문(Syntax) 통합

리버포드 버전 1.0.0은 providers와 상호작용하기 위한 구문을 통합하는 데 중점을 두었습니다.
이전에는 ref.watch(provider)useProvider(provider)watch(provider)와 같이 provider를 읽는 구문이 비슷하지만 서로 다른 구문이 많았습니다.
버전 1.0.0에서는 구문이 하나만 남았습니다: ref.watch(provider)`. 나머지는 제거되었습니다.

따라서:

  • useProvider가 제거되고 HookConsumerWidget이 대신 사용됩니다.

    이전:

    class Example extends HookWidget {

    Widget build(BuildContext context) {
    useState(...);
    int count = useProvider(counterProvider);
    ...
    }
    }

    변경후:

    class Example extends HookConsumerWidget {

    Widget build(BuildContext context, WidgetRef ref) {
    useState(...);
    int count = ref.watch(counterProvider);
    ...
    }
    }
  • ConsumerWidgetbuildConsumerbuilder의 프로토타입이 변경되었습니다.

    이전:

    class Example extends ConsumerWidget {

    Widget build(BuildContext context, ScopedReader watch) {
    int count = watch(counterProvider);
    ...
    }
    }

    Consumer(
    builder: (context, watch, child) {
    int count = watch(counterProvider);
    ...
    }
    )

    변경후:

    class Example extends ConsumerWidget {

    Widget build(BuildContext context, WidgetRef ref) {
    int count = ref.watch(counterProvider);
    ...
    }
    }

    Consumer(
    builder: (context, ref, child) {
    int count = ref.watch(counterProvider);
    ...
    }
    )
  • context.readref.read로 대체되어 제거됩니다.

    이전:

    class Example extends StatelessWidget {

    Widget build(BuildContext context) {
    SomeButton(
    onPressed: () => context.read(provider.notifier).doSomething(),
    );
    }
    }

    변경후:

    class Example extends ConsumerWidget {

    Widget build(BuildContext context, WidgetRef ref) {
    SomeButton(
    onPressed: () => ref.read(provider.notifier).doSomething(),
    );
    }
    }

StateProvider 업데이트

StateProviderStateNotifierProvider와 일치하도록 업데이트 되었습니다.

이전에는 ref.watch(StateProvider)를 실행하면 StateController 인스턴스가 반환되었습니다. 이제 StateController의 상태만 반환합니다.

마이그레이션을 위한 몇 가지 솔루션이 있습니다.
코드를 수정하지 않고 상태만 가져온 경우 다음에서 변경할 수 있습니다:

final provider = StateProvider<int>(...);

Consumer(
builder: (context, ref, child) {
StateController<int> count = ref.watch(provider);

return Text('${count.state}');
}
)

에서 다음과 같이:

final provider = StateProvider<int>(...);

Consumer(
builder: (context, ref, child) {
int count = ref.watch(provider);

return Text('${count}');
}
)

또는 새로운 StateProvider.state를 사용하여 이전 동작을 유지할 수 있습니다.

final provider = StateProvider<int>(...);

Consumer(
builder: (context, ref, child) {
StateController<int> count = ref.watch(provider.state);

return Text('${count.state}');
}
)