riverpod v1からuserProviderが廃止によって起こること

こんにちは、株式会社Pentagonでエンジニアをしているtsurumiです。
dev版のriverpodのv1からたくさんの変更点があるとtwitterで見ました。
今回はその変更点について調査しましたので一部を解説します。

【こんな人に読んで欲しい】

・riverpodを現在使っていてv1にしようかなと思っている人
・これからriverpodを使ってみようかなーと思ってるいる人
・flutter_hooks + hooks_riverpodを活用して開発している人

【この記事を読むメリット】

・最新(2021/10/03現在)のriverpodの使い方がわかります
・サンプルコードを2種類載せているので、riverpod初心者の方やFlutter初心者の方でもすぐに試せます。

今までriverpodを活用して開発していた方々にとって、widget側の変更点が多くなりそうです。

目次

useProviderが削除?

今回の変更点の中で私が特に驚いたのは、useProviderが削除されることです。。
私が興味を持った理由は以下の通りです。

While hooks_riverpod doesn't suffer from the problem listed at the start of the issue, the logic wants that hooks_riverpod should also use the same syntax too (both to reduce confusion and simplify maintenance).
(hooks_riverpodは冒頭に挙げた問題を抱えていませんが、論理的にはhooks_riverpodも同じ構文を使うべきです。(混乱を避けメンテナンスを簡単にするため))
As such, useProvider would be deprecated and a ConsumerHookWidget would be introduced. Which means that instead of:
(そのため、useProviderは非推奨になり、ConsumerHookWidgetが導入されます。つまり、次の代わりに:)

class HooksExample extends HookWidget {
@override
Widget build(BuildContext context) {
A value = useProvider(a);
}
}

we'd have: (こうすべき:)

class HooksExample extends ConsumerHookWidget {
@override
Widget build(BuildContext context, WidgetReference ref) {
A value = ref.watch(a);
}
}

This would also clarify that the only purpose of hooks_riverpod is to use both hooks and Riverpod simultaneously.
(これにより明らかになったのは、hooks_riverpodの唯一の目的がフックとriverpodの両方を同時に使用するということです。)

changeNotifierで使用する例

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

final hooksSamplePageNotifierProvider =
    ChangeNotifierProvider((ref) => HooksSamplePageNotifier());

class HooksSamplePageNotifier extends ChangeNotifier {
  int count = 0;

  void increment() {
    count++;
    notifyListeners();
  }
}

class HooksSamplePage extends HookConsumerWidget {
  const HooksSamplePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final provider = hooksSamplePageNotifierProvider;
    final count = ref.watch(provider).count;
    final notifier = ref.read(provider);
    return Scaffold(
      appBar: AppBar(title: const Text('Example')),
      floatingActionButton: FloatingActionButton(
        onPressed: notifier.increment,
        child: const Icon(Icons.add),
      ),
      body: Center(
        child: Text('$count'),
      ),
    );
  }
}

state_notifier + freezedで使用する場合

import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

part 'hooks_sample_page.freezed.dart';

final hooksSamplePageNotifierProvider =
    StateNotifierProvider<HooksSamplePageNotifier, HooksSamplePageState>(
        (ref) => HooksSamplePageNotifier());

@freezed
abstract class HooksSamplePageState with _$HooksSamplePageState {
  const factory HooksSamplePageState({
    @Default(0) int count,
  }) = _HooksSamplePageState;
}

class HooksSamplePageNotifier extends StateNotifier<HooksSamplePageState> {
  HooksSamplePageNotifier() : super(const HooksSamplePageState());

  void increment() {
    state = state.copyWith(count: state.count + 1);
  }
}

class HooksSamplePage extends HookConsumerWidget {
  const HooksSamplePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final provider = hooksSamplePageNotifierProvider;
    final count = ref.watch(provider).count;
    final notifier = ref.read(provider.notifier);
    return Scaffold(
      appBar: AppBar(title: const Text('Example')),
      floatingActionButton: FloatingActionButton(
        onPressed: notifier.increment,
        child: const Icon(Icons.add),
      ),
      body: Center(
        child: Text('$count'),
      ),
    );
  }
}

まとめ

  • useProviderを使用して状態のチェックを行っている方は、こちらのバージョンをv1にすると useProviderのところに赤い警告が出ます。
    この問題を解決するためには、全て ref.watchに変更すれば一旦大丈夫です。関数などの使用部分については ref.readなどを使いましょう。
  • 今後、riverpodの作者はdartチームの開発に左右されますが、ref.watchから@watch(provider)で状態のチェックを行えるようにしたいそうです。
  • 結論として、まだ開発中なので、正式リリースが出るまでバージョンを上げなくていいかもしれませんね。
  • またリリース版のv1が出たら記事を新しく書きたいと思います!
採用情報はこちら
目次