# 【ProviderとRiverpodの違い④】安全性の欠如

> Flutterにおける状態管理のためのProviderとRiverpodの違いについて、今回の記事では「安全性の欠如」を解決する方法について解説します。

- 公開日: 2024-10-17
- 更新日: 2024-10-18
- 著者: Matsu
- タグ: Flutter, Riverpod
- URL: https://tech.anycloud.co.jp/articles/provider-vs-riverpod-safety

---

## はじめに

<div class="link-card-wrap"><a class="link-card" href="/articles/provider-vs-riverpod-difficult-combine/" target="_blank" rel="noopener noreferrer"><span class="link-card-body"><span class="link-card-title">【ProviderとRiverpodの違い③】結合が難しくエラーが発生しやすい</span><span class="link-card-description">Flutterにおける状態管理のためのProviderとRiverpodの違いについて、今回の記事では「結合が難しくエラーが発生しやすい」を解決する方法について解説します。</span><span class="link-card-meta"><img class="link-card-favicon" src="./linkcard-01-favicon.ico" alt=""><span class="link-card-domain">tech.anycloud.co.jp</span></span></span><img class="link-card-image" src="./linkcard-01-image.webp" alt=""></a></div>

前回に引き続き、今回もRiverpodのモチベーションについて解説していきます。

<div class="link-card-wrap"><a class="link-card" href="https://riverpod.dev/ja/docs/from_provider/motivation" target="_blank" rel="noopener noreferrer"><span class="link-card-body"><span class="link-card-title">モチベーション | Riverpod</span><span class="link-card-description">この記事は、なぜ Riverpod が存在するのかを詳しく説明することを目的としています。</span><span class="link-card-meta"><img class="link-card-favicon" src="./linkcard-02-favicon.svg" alt=""><span class="link-card-domain">riverpod.dev</span></span></span><img class="link-card-image" src="./linkcard-02-image.webp" alt=""></a></div>

今回の記事では、「[安全性の欠如](https://riverpod.dev/ja/docs/from_provider/motivation#%E5%AE%89%E5%85%A8%E6%80%A7%E3%81%AE%E6%AC%A0%E5%A6%82)」というセクションを掘り下げていきます。

## Providerにおける安全性の欠如

### 公式ドキュメントの説明

> Provider では、リファクタリングや大規模な変更中に `ProviderNotFoundException` が発生することが一般的です。
> 
> 実際、このランタイム例外は Riverpod が作られた主な理由の 1 つです。
> 
> Riverpod では、この例外は発生しません。

### Providerにおける安全性の欠如とProviderNotFoundException

Providerでは、ウィジェットがその必要とするプロバイダーにアクセスできないときに`ProviderNotFoundException`が発生します。

これは、プロバイダーが適切にスコープされていないか、リファクタリング中にプロバイダーの配置が変更された場合によく発生します。

<figure><img src="./image-001.webp" alt="" width="400" height="111"></figure>

```dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        // ProviderはHomeScreenの外側に配置されていないため、HomeScreenでProviderを探すと例外が発生する
        body: HomeScreen(),
      ),
    );
  }
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    // Provider.ofを使用してデータを取得しようとしていますが、Providerが存在しないため例外が発生する
    final value = Provider.of<int>(context);
    return Center(
      child: Text('Value is $value'),
    );
  }
}
```

## Riverpodにおける安全性の向上

Riverpodでは、プロバイダーの使用がコンパイル時にチェックされるため、`ProviderNotFoundException`のような例外が発生することはありません。

Riverpodは、すべてのプロバイダーをグローバルにアクセス可能なものとして扱い、それぞれが一意の参照を持つため、ウィジェットの場所に依存することなく安全にアクセスすることができます。

以下の例では、`ProviderScope`内で定義された`myProvider`を使用しています。

`myProvider`はアプリケーションのどの部分からでも安全にアクセスでき、`ProviderNotFoundException`は発生しません。

```dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final myProvider = Provider<int>((ref) => 10);

void main() {
  runApp(
    ProviderScope(
      child: MaterialApp(
        home: Scaffold(
          body: Consumer(
            builder: (context, ref, _) {
              final value = ref.watch(myProvider);
              return Text('Value is $value');
            },
          ),
        ),
      ),
    ),
  );
}
```

## まとめ

RiverpodはProviderの安全性の問題を解決して、より安全で信頼性の高い状態管理を提供しています。

Providerの例外が開発中の問題となることを防ぎ、リファクタリングやプロジェクトのスケールアップが容易になります。

これにより、開発プロセスがスムーズになり、エラーのリスクが低減されるでしょう。

次回、「状態の破棄が難しい」デュエルスタンバイ！

<div class="link-card-wrap"><a class="link-card" href="/articles/provider-vs-riverpod-discard-state/" target="_blank" rel="noopener noreferrer"><span class="link-card-body"><span class="link-card-title">【ProviderとRiverpodの違い⑤】状態の破棄が難しい</span><span class="link-card-description">Flutterにおける状態管理のためのProviderとRiverpodの違いについて、今回の記事では「状態の破棄が難しい」を解決する方法について解説します。</span><span class="link-card-meta"><img class="link-card-favicon" src="./linkcard-03-favicon.ico" alt=""><span class="link-card-domain">tech.anycloud.co.jp</span></span></span><img class="link-card-image" src="./linkcard-03-image.webp" alt=""></a></div>
