1
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Flutterで開発するならRiverpod使おうZE! -Riverpodの簡単な使い方-

Last updated at Posted at 2021-06-04

Flutterで開発をしている皆さんこんにちは,今回はRiverpodの使い方を紹介してきます.
私はちょっと特殊な経歴で,React.jsを4ヶ月くらい勉強してから,Flutterに鞍替えした人間です.
そんな僕からすると「なんでRiverpod使わないの?」って思うくらい使いやすいです.

まず皆さんに言いたいのが,FlutterはどんどんReactに近づいているということ.
特にDartパッケージのProviderが登場したあたりから,Reactに近づいている印象です.
state managementが非常にReactに似ていると思います.

さらにFlutter hooksというパッケージが出てきたので,さらにReactに近づくことになりました.
というよりFlutter hooksの最初の説明にReactのhooksの真似ですと書かれています.

今回はflutter_hooksとhooks_riverpodを使ったstate manegementのやり方を解説します.

ステップ1:インストール

今回はflutter_hooksという別のパッケージを使って,hooks_riverpodという状態管理用のパッケージを動かすイメージです.
つまり2つのパッケージをインストールしなければいけません.

以下のようにpubspec.yamlを編集します.
これは,この記事を書いた当時のバージョンなので実際のバージョンを知るために こちら

pabspec.yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_hooks: ^0.17.0
  hooks_riverpod: ^0.14.0+4

ステップ2:下準備

Riverpodを使うためには,main.dartを少し改良しなければいけません.
具体的には以下の通りです.

main.dart
void main() {
  runApp(
    ProviderScope(
      child: MyApp(),
    ),
  );
}

上のようにrunApp()の中にProviderScopeを追加します.

ステップ3:stateを定義する

やっとstateを定義するところまで来ました.
stateを定義すれば,それ以降stateを定義したファイルをimportすれば,どこでもstateを読み取り,書き取りすることができます.
実際に定義の仕方をお見せしましょう.

providers.dart
final helloWorldProvider = Provider((_) => 'Hello world');

今回はProviderの名前がhelloWorldProviderになります.値を呼び出すときはこの名前を使用します.
またProviderの初期値,つまり初期のstateがHello worldとなります.他の状態管理と同様にこの値は後から変更することができます.

ここで注目してほしいのが,providers.dartというファイルで定義されているということ.
私のおすすめはmain.dartなどで使う場合でも,このコードはstate定義用の専用ファイルを作成しておくのがおすすめです.
stateが何個あろうと,state定義用ファイルを一つだけimportするだけで,全てのstateの読み書きができるので便利です.

実はProvider以外にもstateを定義する方法があるのですが,今回は私がよく使うものを一つだけ教えます.
それはStateProvderです.

providers.dart
final helloWorldProvider = StateProvider((_) => 'Hello world');

このようにProviderと同じように使えますが,StateProviderの方が値を読み取ることに優れています.
値の読み取り方については別の章で教えます.

ステップ4:値を読み取る・変更する

まずは値の読み取り方を学びましょう.
実はRiverpodでは値を変更するのは,値を読み取ることの応用となっています.
早速,具体例から学んでいきましょう.

値を読み取る

main.dart
final counterProvider = StateProvider((ref) => 0);

class Count extends HookWidget {
  @override
  Widget build(BuildContext context) {
    int count = useProvider(counterProvider).state;

    return Text('$count');
  }
}

ここで重要なのは,通常classを作成する場合はStatelessWidgetを使用しますが,今回はflutter_hooksというパッケージを導入しているため,HookWidgetという特殊なWidgetを継承できます.
ここでHookWidgetに関して説明すると,HookWidgetStatelessWidgetを内包しているので,StatelessWidgetでできることは全てできます.
HookWidgetではそれプラスhooksというものが使えます.

そのhooksの一つが,useProviderです.上のようにしてcountProviderの中に入っている値を代入することができます.
この値はProviderの中の値が変更された時も,しっかりと反映されますのでご安心ください.

ここで注意しなければならないのが,useProvider(counterProvider).stateというコードです.
.stateという書き方ができるのは,StateProviderで定義した場合のみです.
普通のProviderで定義した場合は,.stateと書いてもエラーが出るだけです.

ちょっと一息

最近のコーディングでは,めんどくさいのでStatelessWidgetを一回も継承していません.
理由はhooksを使うかどうかは,classを作成している段階ではわからない時もあります.しかしhooksを使おうと使うまいとHookWidgetを継承しておけば事足りるので,StatelessWidgetを使う必要はないのです.
むしろclassを作成するたびに,hooksを使うかどうかを考えて,StatelessWidgetHookWidgetのどちらを使うか考えていたら,あっという間に時間は過ぎていきます.

値を変更する

ここからは少し応用編になります.
Riverpodでは値の読み取り方は様々です.
先ほどはその中で最も簡単な方法をご紹介しました.

値を変更する場合はもう一つの値の読み取り方を応用します.
具体例を見ていきましょう.
カウンターの場合

main.dart
final counterProvider = StateProvider((ref) => 0);

@override
Widget build(BuildContext context) {
  return RaisedButton(
    onPressed: () => context.read(counterProvider).state++,
    child: Text('increment'),
  );
}

文字列の場合

main.dart
final textProvider = StateProvider((ref) => 0);

@override
Widget build(BuildContext context) {
  return ElevatedButton(
    onPressed: () {
      context.read(textProvider).state = 'Hello hello everybody^_^';
    },
    child: Text('increment'),
  );
}

このように書くことができます.
基本は以上です.また今度応用編も書くかもしれません.

1
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?