<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Riverpod</title>
	<atom:link href="https://techgrowup.net/tag/riverpod/feed/" rel="self" type="application/rss+xml" />
	<link>https://techgrowup.net</link>
	<description>エンジニアを強くする</description>
	<lastBuildDate>Sat, 12 Oct 2024 05:13:49 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://techgrowup.net/wp-content/uploads/2021/05/hp-icon-150x150.png</url>
	<title>Riverpod</title>
	<link>https://techgrowup.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Flutter開発入門47 hooks_riverpodでのStreamProvider、NotifierProvider、StateNotifierProvider、ChangeNotifierProviderの使い方</title>
		<link>https://techgrowup.net/flutter-hooks-riverpod-each-provider/</link>
					<comments>https://techgrowup.net/flutter-hooks-riverpod-each-provider/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[techgrowup]]></dc:creator>
		<pubDate>Sat, 12 Oct 2024 05:12:49 +0000</pubDate>
				<category><![CDATA[Flutter]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Dart]]></category>
		<category><![CDATA[Hooks]]></category>
		<category><![CDATA[Provider]]></category>
		<category><![CDATA[Riverpod]]></category>
		<category><![CDATA[アプリ開発]]></category>
		<guid isPermaLink="false">https://techgrowup.net/?p=1955</guid>

					<description><![CDATA[はじめに hooks_riverpodは、Flutterアプリの開発において、強力で柔軟な状態管理を提供します。特に、非同期処理を扱うためのStreamProvider、状態を管理するためのNotifierProvide [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">はじめに</h1>



<p class="wp-block-paragraph"><strong><code>hooks_riverpod</code>は、Flutterアプリの開発において、強力で柔軟な状態管理を提供します。特に、非同期処理を扱うための<code>StreamProvider</code></strong>、状態を管理するための<code>NotifierProvider</code><strong>や</strong><code>StateNotifierProvider</code><strong>、および従来の<code>ChangeNotifier</code>に基づいた</strong><code>ChangeNotifierProvider</code>は、それぞれの場面で最適なソリューションを提供します。</p>



<p class="wp-block-paragraph">この記事では、<strong>StreamProvider、NotifierProvider、StateNotifierProvider、ChangeNotifierProvider</strong>の使い方について詳しく解説します。Flutter開発を効率化し、状態管理をよりシンプルにするための実践的な知識を提供します。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">hooks_riverpodとは？</h2>



<p class="wp-block-paragraph"><code>hooks_riverpod</code>は、<code>Riverpod</code>の状態管理機能と<code>Flutter Hooks</code>のフック機能を統合したライブラリです。Riverpodによる強力な状態管理に、Flutter Hooksを組み合わせることで、ウィジェットのライフサイクルに応じた簡潔な状態管理を実現します。</p>



<p class="wp-block-paragraph">この記事では、特に以下のプロバイダについて詳しく見ていきます。</p>



<ul class="wp-block-list">
<li><strong><code>StreamProvider</code></strong>：非同期データのストリームを管理。</li>



<li><strong><code>NotifierProvider</code></strong>：<code>Notifier</code>クラスをベースにした状態管理。</li>



<li><strong><code>StateNotifierProvider</code></strong>：<code>StateNotifier</code>を使って状態を管理する。</li>



<li><strong><code>ChangeNotifierProvider</code></strong>：従来の<code>ChangeNotifier</code>ベースの状態管理。</li>
</ul>



<p class="wp-block-paragraph">※<code>hooks_riverpod</code>が導入が済んでいない方は以下記事を確認してください。</p>



<figure class="wp-block-embed is-type-wp-embed is-provider-techgrowup wp-block-embed-techgrowup"><div class="wp-block-embed__wrapper">

<a target="_self" href="https://techgrowup.net/flutter-hooks-riverpod/" title="Flutter開発入門46 hooks_riverpodの使い方：効率的な状態管理を実現" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img decoding="async" width="160" height="90" src="https://techgrowup.net/wp-content/uploads/2024/10/flutter-hooks-riverpod-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://techgrowup.net/wp-content/uploads/2024/10/flutter-hooks-riverpod-160x90.webp 160w, https://techgrowup.net/wp-content/uploads/2024/10/flutter-hooks-riverpod-1024x585.webp 1024w, https://techgrowup.net/wp-content/uploads/2024/10/flutter-hooks-riverpod-768x439.webp 768w, https://techgrowup.net/wp-content/uploads/2024/10/flutter-hooks-riverpod-120x68.webp 120w, https://techgrowup.net/wp-content/uploads/2024/10/flutter-hooks-riverpod-320x180.webp 320w, https://techgrowup.net/wp-content/uploads/2024/10/flutter-hooks-riverpod-376x212.webp 376w, https://techgrowup.net/wp-content/uploads/2024/10/flutter-hooks-riverpod.webp 1200w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">Flutter開発入門46 hooks_riverpodの使い方：効率的な状態管理を実現</div><div class="blogcard-snippet internal-blogcard-snippet">Flutterアプリでの状態管理に欠かせないhooks_riverpodを徹底解説。useProviderは廃止され、WidgetRefとref.watchを使った効率的な状態管理方法を解説します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://techgrowup.net" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">techgrowup.net</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2024.10.12</div></div></div></div></a>
</div></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">StreamProviderの使い方</h2>



<p class="wp-block-paragraph"><code>StreamProvider</code>は、非同期でデータのストリームを提供する際に使用します。たとえば、リアルタイムに更新されるデータや、ストリームAPIのデータを扱う場合に便利です。</p>



<h3 class="wp-block-heading">例：StreamProviderでのリアルタイムカウント</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="final countStreamProvider = StreamProvider&lt;int&gt;((ref) {
  return Stream.periodic(const Duration(seconds: 1), (count) =&gt; count);
});

class HomeScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final asyncValue = ref.watch(countStreamProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('StreamProvider Example')),
      body: Center(
        child: asyncValue.when(
          data: (count) =&gt; Text('Count: $count'),
          loading: () =&gt; CircularProgressIndicator(),
          error: (err, stack) =&gt; Text('Error: $err'),
        ),
      ),
    );
  }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> countStreamProvider = </span><span style="color: #4EC9B0">StreamProvider</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">int</span><span style="color: #D4D4D4">&gt;((ref) {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Stream</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">periodic</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Duration</span><span style="color: #D4D4D4">(seconds: </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">), (count) =&gt; count);</span></span>
<span class="line"><span style="color: #D4D4D4">});</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">HomeScreen</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ConsumerWidget</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">@override</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">Widget</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">build</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">BuildContext</span><span style="color: #D4D4D4"> context, </span><span style="color: #4EC9B0">WidgetRef</span><span style="color: #D4D4D4"> ref) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> asyncValue = ref.</span><span style="color: #DCDCAA">watch</span><span style="color: #D4D4D4">(countStreamProvider);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Scaffold</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">      appBar: </span><span style="color: #4EC9B0">AppBar</span><span style="color: #D4D4D4">(title: </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;StreamProvider Example&#39;</span><span style="color: #D4D4D4">)),</span></span>
<span class="line"><span style="color: #D4D4D4">      body: </span><span style="color: #4EC9B0">Center</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">        child: asyncValue.</span><span style="color: #C586C0">when</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">          data: (count) =&gt; </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Count: $</span><span style="color: #9CDCFE">count</span><span style="color: #CE9178">&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">          loading: () =&gt; </span><span style="color: #4EC9B0">CircularProgressIndicator</span><span style="color: #D4D4D4">(),</span></span>
<span class="line"><span style="color: #D4D4D4">          error: (err, stack) =&gt; </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Error: $</span><span style="color: #9CDCFE">err</span><span style="color: #CE9178">&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">        ),</span></span>
<span class="line"><span style="color: #D4D4D4">      ),</span></span>
<span class="line"><span style="color: #D4D4D4">    );</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">解説</p>



<ul class="wp-block-list">
<li><strong><code>StreamProvider</code></strong>：非同期ストリームをプロバイダとして提供し、UIにリアルタイムで反映できます。</li>



<li><strong><code>Stream.periodic</code></strong>：一定の間隔でデータを発行するストリームの生成方法です。</li>



<li><strong><code>asyncValue.when</code></strong>：<code>StreamProvider</code>の状態に応じて、データ・ローディング・エラーのそれぞれを表示します。</li>
</ul>



<h2 class="wp-block-heading">NotifierProviderの使い方</h2>



<p class="wp-block-paragraph"><code>NotifierProvider</code>は、<strong><code>Notifier</code>クラス</strong>に基づいたプロバイダで、<code>Notifier</code>を使って状態を管理し、それに応じてUIをリビルドする際に使用します。<code>Notifier</code>は、状態を持たせ、<code>notifyListeners</code>で更新するシンプルな仕組みです。</p>



<h3 class="wp-block-heading">例：NotifierProviderでカウンターを管理</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="class CounterNotifier extends Notifier&lt;int&gt; {
  @override
  int build() =&gt; 0;

  void increment() =&gt; state++;
}

final counterProvider = NotifierProvider&lt;CounterNotifier, int&gt;(() {
  return CounterNotifier();
});

class HomeScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('NotifierProvider Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Count: $count', style: const TextStyle(fontSize: 40)),
            ElevatedButton(
              onPressed: () =&gt; ref.read(counterProvider.notifier).increment(),
              child: const Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">CounterNotifier</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Notifier</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">int</span><span style="color: #D4D4D4">&gt; {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">@override</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">int</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">build</span><span style="color: #D4D4D4">() =&gt; </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">increment</span><span style="color: #D4D4D4">() =&gt; state++;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> counterProvider = </span><span style="color: #4EC9B0">NotifierProvider</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">CounterNotifier</span><span style="color: #D4D4D4">, </span><span style="color: #4EC9B0">int</span><span style="color: #D4D4D4">&gt;(() {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">CounterNotifier</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">});</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">HomeScreen</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ConsumerWidget</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">@override</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">Widget</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">build</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">BuildContext</span><span style="color: #D4D4D4"> context, </span><span style="color: #4EC9B0">WidgetRef</span><span style="color: #D4D4D4"> ref) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> count = ref.</span><span style="color: #DCDCAA">watch</span><span style="color: #D4D4D4">(counterProvider);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Scaffold</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">      appBar: </span><span style="color: #4EC9B0">AppBar</span><span style="color: #D4D4D4">(title: </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;NotifierProvider Example&#39;</span><span style="color: #D4D4D4">)),</span></span>
<span class="line"><span style="color: #D4D4D4">      body: </span><span style="color: #4EC9B0">Center</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">        child: </span><span style="color: #4EC9B0">Column</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">          mainAxisAlignment: </span><span style="color: #4EC9B0">MainAxisAlignment</span><span style="color: #D4D4D4">.center,</span></span>
<span class="line"><span style="color: #D4D4D4">          children: [</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Count: $</span><span style="color: #9CDCFE">count</span><span style="color: #CE9178">&#39;</span><span style="color: #D4D4D4">, style: </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">TextStyle</span><span style="color: #D4D4D4">(fontSize: </span><span style="color: #B5CEA8">40</span><span style="color: #D4D4D4">)),</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #4EC9B0">ElevatedButton</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">              onPressed: () =&gt; ref.</span><span style="color: #DCDCAA">read</span><span style="color: #D4D4D4">(counterProvider.notifier).</span><span style="color: #DCDCAA">increment</span><span style="color: #D4D4D4">(),</span></span>
<span class="line"><span style="color: #D4D4D4">              child: </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Increment&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">            ),</span></span>
<span class="line"><span style="color: #D4D4D4">          ],</span></span>
<span class="line"><span style="color: #D4D4D4">        ),</span></span>
<span class="line"><span style="color: #D4D4D4">      ),</span></span>
<span class="line"><span style="color: #D4D4D4">    );</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">解説</p>



<ul class="wp-block-list">
<li><strong><code>Notifier</code></strong>：シンプルな状態管理クラスで、状態を管理し、変更があった際にリビルドをトリガーします。</li>



<li><strong><code>NotifierProvider</code></strong>：<code>Notifier</code>をプロバイダとして使用し、状態を管理します。</li>



<li><strong><code>ref.watch(counterProvider)</code></strong>：カウンターの現在の値を監視し、UIに反映します。</li>



<li><strong><code>ref.read(counterProvider.notifier).increment()</code></strong>：<code>Notifier</code>のメソッドを使って状態を変更します。</li>
</ul>



<h2 class="wp-block-heading">StateNotifierProviderの使い方</h2>



<p class="wp-block-paragraph"><code>StateNotifierProvider</code>は、<strong><code>StateNotifier</code>クラス</strong>を使って、状態を細かく管理したいときに便利です。<code>StateNotifier</code>は、状態を変更するためのメソッドを定義でき、状態の変更を安全に管理できます。</p>



<h3 class="wp-block-heading">例：StateNotifierProviderでカウンターを管理</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="class CounterStateNotifier extends StateNotifier&lt;int&gt; {
  CounterStateNotifier() : super(0);

  void increment() =&gt; state++;
}

final counterStateNotifierProvider =
    StateNotifierProvider&lt;CounterStateNotifier, int&gt;((ref) {
  return CounterStateNotifier();
});

class HomeScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterStateNotifierProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('StateNotifierProvider Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Count: $count', style: const TextStyle(fontSize: 40)),
            ElevatedButton(
              onPressed: () =&gt;
                  ref.read(counterStateNotifierProvider.notifier).increment(),
              child: const Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">CounterStateNotifier</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">StateNotifier</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">int</span><span style="color: #D4D4D4">&gt; {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">CounterStateNotifier</span><span style="color: #D4D4D4">() : </span><span style="color: #569CD6">super</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">increment</span><span style="color: #D4D4D4">() =&gt; state++;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> counterStateNotifierProvider =</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">StateNotifierProvider</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">CounterStateNotifier</span><span style="color: #D4D4D4">, </span><span style="color: #4EC9B0">int</span><span style="color: #D4D4D4">&gt;((ref) {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">CounterStateNotifier</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">});</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">HomeScreen</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ConsumerWidget</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">@override</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">Widget</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">build</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">BuildContext</span><span style="color: #D4D4D4"> context, </span><span style="color: #4EC9B0">WidgetRef</span><span style="color: #D4D4D4"> ref) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> count = ref.</span><span style="color: #DCDCAA">watch</span><span style="color: #D4D4D4">(counterStateNotifierProvider);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Scaffold</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">      appBar: </span><span style="color: #4EC9B0">AppBar</span><span style="color: #D4D4D4">(title: </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;StateNotifierProvider Example&#39;</span><span style="color: #D4D4D4">)),</span></span>
<span class="line"><span style="color: #D4D4D4">      body: </span><span style="color: #4EC9B0">Center</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">        child: </span><span style="color: #4EC9B0">Column</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">          mainAxisAlignment: </span><span style="color: #4EC9B0">MainAxisAlignment</span><span style="color: #D4D4D4">.center,</span></span>
<span class="line"><span style="color: #D4D4D4">          children: [</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Count: $</span><span style="color: #9CDCFE">count</span><span style="color: #CE9178">&#39;</span><span style="color: #D4D4D4">, style: </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">TextStyle</span><span style="color: #D4D4D4">(fontSize: </span><span style="color: #B5CEA8">40</span><span style="color: #D4D4D4">)),</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #4EC9B0">ElevatedButton</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">              onPressed: () =&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">                  ref.</span><span style="color: #DCDCAA">read</span><span style="color: #D4D4D4">(counterStateNotifierProvider.notifier).</span><span style="color: #DCDCAA">increment</span><span style="color: #D4D4D4">(),</span></span>
<span class="line"><span style="color: #D4D4D4">              child: </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Increment&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">            ),</span></span>
<span class="line"><span style="color: #D4D4D4">          ],</span></span>
<span class="line"><span style="color: #D4D4D4">        ),</span></span>
<span class="line"><span style="color: #D4D4D4">      ),</span></span>
<span class="line"><span style="color: #D4D4D4">    );</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">解説</p>



<ul class="wp-block-list">
<li><strong><code>StateNotifier</code></strong>：状態を管理するためのクラスで、複雑なロジックにも対応できます。</li>



<li><strong><code>StateNotifierProvider</code></strong>：<code>StateNotifier</code>をプロバイダとして使用し、状態の管理を行います。</li>



<li><strong><code>state</code></strong>：現在の状態を保持するプロパティで、状態が更新されるとリビルドがトリガーされます。</li>
</ul>



<h2 class="wp-block-heading">ChangeNotifierProviderの使い方</h2>



<p class="wp-block-paragraph"><code>ChangeNotifierProvider</code>は、従来の<code>ChangeNotifier</code>ベースの状態管理を使いたい場合に有効です。<code>ChangeNotifier</code>は、<code>notifyListeners</code>メソッドを使って状態の更新を通知します。</p>



<h3 class="wp-block-heading">例：ChangeNotifierProviderでカウンターを管理</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="class CounterChangeNotifier extends ChangeNotifier {
  int _count = 0;
  int get count =&gt; _count;

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

final counterChangeNotifierProvider =
    ChangeNotifierProvider&lt;CounterChangeNotifier&gt;((ref) {
  return CounterChangeNotifier();
});

class HomeScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final counter = ref.watch(counterChangeNotifierProvider);

    return Scaffold(
      appBar: AppBar(title: const Text('ChangeNotifierProvider Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Count: ${counter.count}',
                style: const TextStyle(fontSize: 40)),
            ElevatedButton(
              onPressed: () =&gt; counter.increment(),
              child: const Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">CounterChangeNotifier</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ChangeNotifier</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">int</span><span style="color: #D4D4D4"> _count = </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">int</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">get</span><span style="color: #D4D4D4"> count =&gt; _count;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">increment</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    _count++;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">notifyListeners</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> counterChangeNotifierProvider =</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #4EC9B0">ChangeNotifierProvider</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">CounterChangeNotifier</span><span style="color: #D4D4D4">&gt;((ref) {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">CounterChangeNotifier</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">});</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">HomeScreen</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ConsumerWidget</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">@override</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">Widget</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">build</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">BuildContext</span><span style="color: #D4D4D4"> context, </span><span style="color: #4EC9B0">WidgetRef</span><span style="color: #D4D4D4"> ref) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> counter = ref.</span><span style="color: #DCDCAA">watch</span><span style="color: #D4D4D4">(counterChangeNotifierProvider);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Scaffold</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">      appBar: </span><span style="color: #4EC9B0">AppBar</span><span style="color: #D4D4D4">(title: </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;ChangeNotifierProvider Example&#39;</span><span style="color: #D4D4D4">)),</span></span>
<span class="line"><span style="color: #D4D4D4">      body: </span><span style="color: #4EC9B0">Center</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">        child: </span><span style="color: #4EC9B0">Column</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">          mainAxisAlignment: </span><span style="color: #4EC9B0">MainAxisAlignment</span><span style="color: #D4D4D4">.center,</span></span>
<span class="line"><span style="color: #D4D4D4">          children: [</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Count: ${</span><span style="color: #9CDCFE">counter</span><span style="color: #CE9178">.</span><span style="color: #9CDCFE">count</span><span style="color: #CE9178">}&#39;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                style: </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">TextStyle</span><span style="color: #D4D4D4">(fontSize: </span><span style="color: #B5CEA8">40</span><span style="color: #D4D4D4">)),</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #4EC9B0">ElevatedButton</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">              onPressed: () =&gt; counter.</span><span style="color: #DCDCAA">increment</span><span style="color: #D4D4D4">(),</span></span>
<span class="line"><span style="color: #D4D4D4">              child: </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Increment&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">            ),</span></span>
<span class="line"><span style="color: #D4D4D4">          ],</span></span>
<span class="line"><span style="color: #D4D4D4">        ),</span></span>
<span class="line"><span style="color: #D4D4D4">      ),</span></span>
<span class="line"><span style="color: #D4D4D4">    );</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">解説</p>



<ul class="wp-block-list">
<li><strong><code>ChangeNotifier</code></strong>：リスナーに状態の変更を通知するためのクラスで、従来のFlutterの状態管理でよく使われます。</li>



<li><strong><code>ChangeNotifierProvider</code></strong>：<code>ChangeNotifier</code>をプロバイダとして使用し、<code>notifyListeners</code>でUIをリビルドします。</li>
</ul>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">Flutterでの状態管理において、<strong><code>hooks_riverpod</code>は強力なツールです。今回紹介した<code>StreamProvider</code></strong>、<strong><code>NotifierProvider</code></strong>、<strong><code>StateNotifierProvider</code></strong>、および<code>ChangeNotifierProvider</code>を適切に使い分けることで、アプリケーションの規模に関わらず、効率的に状態を管理できます。それぞれのプロバイダは特定のユースケースに最適化されており、状態の再利用や非同期データの管理に役立ちます。</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://techgrowup.net/flutter-hooks-riverpod-each-provider/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Flutter開発入門46 hooks_riverpodの使い方：効率的な状態管理を実現</title>
		<link>https://techgrowup.net/flutter-hooks-riverpod/</link>
					<comments>https://techgrowup.net/flutter-hooks-riverpod/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[techgrowup]]></dc:creator>
		<pubDate>Sat, 12 Oct 2024 04:55:31 +0000</pubDate>
				<category><![CDATA[Flutter]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Dart]]></category>
		<category><![CDATA[Hooks]]></category>
		<category><![CDATA[Riverpod]]></category>
		<category><![CDATA[アプリ開発]]></category>
		<guid isPermaLink="false">https://techgrowup.net/?p=1951</guid>

					<description><![CDATA[はじめに hooks_riverpodは、Flutterでの状態管理ライブラリRiverpodとフック機能Flutter Hooksを組み合わせた強力なパッケージです。hooks_riverpodを使うことで、状態管理が [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">はじめに</h1>



<p class="wp-block-paragraph"><code>hooks_riverpod</code>は、Flutterでの状態管理ライブラリ<code>Riverpod</code>とフック機能<code>Flutter Hooks</code>を組み合わせた強力なパッケージです。<code>hooks_riverpod</code>を使うことで、状態管理がシンプルになり、状態に応じたUIの更新を直感的に行えるようになります。特に、フックを活用することで、状態の管理やリソースのクリーンアップを簡潔に記述できるため、より効率的にFlutterアプリケーションを開発できます。</p>



<p class="wp-block-paragraph">この記事では、<strong><code>hooks_riverpod</code>のセットアップから基本的な使い方、実際の利用例</strong>まで詳しく解説します。Flutterの開発経験がある方でも、<code>hooks_riverpod</code>を使うことで、状態管理がさらに快適になるでしょう。</p>



<h2 class="wp-block-heading"><code>hooks_riverpod</code>とは</h2>



<p class="wp-block-paragraph"><code>hooks_riverpod</code>は、<code>Riverpod</code>の状態管理機能と<code>Flutter Hooks</code>のフック機能を統合したパッケージです。<code>Flutter Hooks</code>のコンセプトを取り入れることで、状態管理とUIのロジックをシンプルに記述でき、リソースのクリーンアップなどが簡単になります。</p>



<h3 class="wp-block-heading"><code>hooks_riverpod</code>の主な特徴</h3>



<ul class="wp-block-list">
<li><strong>フックを活用したシンプルな状態管理</strong>：状態の管理やUIの更新がより直感的に行える。</li>



<li><strong>リソースのクリーンアップが簡単</strong>：フックによって、不要になったリソースを自動的に解放できる。</li>



<li><strong>Riverpodのすべての機能に対応</strong>：<code>Riverpod</code>のプロバイダや依存関係管理をそのまま利用可能。</li>
</ul>



<h3 class="wp-block-heading">なぜ<code>hooks_riverpod</code>を使うべきか？</h3>



<ol class="wp-block-list">
<li><strong>UIロジックを簡潔に記述</strong>：状態管理とUIロジックがフックによってシンプルにまとめられます。</li>



<li><strong>効率的なリソース管理</strong>：ウィジェットのライフサイクルに応じてリソースを自動的にクリーンアップ。</li>



<li><strong>パフォーマンス向上</strong>：不要な再レンダリングを防ぐことで、アプリケーションのパフォーマンスが向上します。</li>
</ol>



<h2 class="wp-block-heading"><code>hooks_riverpod</code>のセットアップ</h2>



<p class="wp-block-paragraph">まず、<code>pubspec.yaml</code>に<code>hooks_riverpod</code>パッケージを追加します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="dependencies:
  flutter:
    sdk: flutter
  hooks_riverpod: ^2.5.1" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">dependencies</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">flutter</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">sdk</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">flutter</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">hooks_riverpod</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">^2.5.1</span></span></code></pre></div>



<p class="wp-block-paragraph">次に、依存関係をインストールします。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="flutter pub get" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">flutter</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">pub</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">get</span></span></code></pre></div>



<h2 class="wp-block-heading">hooks_riverpodの基本的な使い方</h2>



<h3 class="wp-block-heading">1. ProviderScopeでアプリを包む</h3>



<p class="wp-block-paragraph">まず、<code>hooks_riverpod</code>を使用する際は、アプリケーション全体を<code>ProviderScope</code>で包む必要があります。これにより、すべてのプロバイダがアプリ全体で利用できるようになります。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;package:flutter_riverpod/flutter_riverpod.dart&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;package:flutter_hooks/flutter_hooks.dart&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;package:flutter/material.dart&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">main</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">runApp</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">ProviderScope</span><span style="color: #D4D4D4">(child: </span><span style="color: #4EC9B0">MyApp</span><span style="color: #D4D4D4">()));</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">MyApp</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">StatelessWidget</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">@override</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">Widget</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">build</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">BuildContext</span><span style="color: #D4D4D4"> context) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">MaterialApp</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">      home: </span><span style="color: #4EC9B0">HomeScreen</span><span style="color: #D4D4D4">(),</span></span>
<span class="line"><span style="color: #D4D4D4">    );</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<h3 class="wp-block-heading">2. <code>ref.watch</code>を使ったプロバイダの状態監視</h3>



<p class="wp-block-paragraph"><code>hooks_riverpod</code>の基本的な状態管理は、プロバイダを使って行います。<code>useProvider</code>は廃止され、代わりに<code>WidgetRef</code><strong>を使って</strong><code>ref.watch</code>で状態を監視するのが現在の標準です。</p>



<h6 class="wp-block-heading">例：シンプルな文字列プロバイダ</h6>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="final helloWorldProvider = Provider&lt;String&gt;((ref) =&gt; 'Hello, World!');

class HomeScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // WidgetRefを使ってプロバイダの状態を監視
    final value = ref.read(helloWorldProvider);

    return Scaffold(
      appBar: AppBar(title: Text('Riverpod with Hooks')),
      body: Center(child: Text(value)),
    );
  }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> helloWorldProvider = </span><span style="color: #4EC9B0">Provider</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4">&gt;((ref) =&gt; </span><span style="color: #CE9178">&#39;Hello, World!&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">HomeScreen</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ConsumerWidget</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">@override</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">Widget</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">build</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">BuildContext</span><span style="color: #D4D4D4"> context, </span><span style="color: #4EC9B0">WidgetRef</span><span style="color: #D4D4D4"> ref) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">// WidgetRefを使ってプロバイダの状態を監視</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> value = ref.</span><span style="color: #DCDCAA">read</span><span style="color: #D4D4D4">(helloWorldProvider);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Scaffold</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">      appBar: </span><span style="color: #4EC9B0">AppBar</span><span style="color: #D4D4D4">(title: </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Riverpod with Hooks&#39;</span><span style="color: #D4D4D4">)),</span></span>
<span class="line"><span style="color: #D4D4D4">      body: </span><span style="color: #4EC9B0">Center</span><span style="color: #D4D4D4">(child: </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(value)),</span></span>
<span class="line"><span style="color: #D4D4D4">    );</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<h3 class="wp-block-heading">3. <code>StateProvider</code>を使った状態変更</h3>



<p class="wp-block-paragraph"><code>StateProvider</code>を使えば、カウンターのような状態を簡単に管理できます。<code>WidgetRef</code>を使って、<code>ref.watch</code><strong>や</strong><code>ref.read</code>を活用し、状態の監視や変更を行います。</p>



<h6 class="wp-block-heading">例：カウンターアプリの実装</h6>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="final counterProvider = StateProvider&lt;int&gt;((ref) =&gt; 0);

class HomeScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // カウンターの値を監視
    final count = ref.watch(counterProvider);

    return Scaffold(
      appBar: AppBar(title: Text('Counter Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Count: $count', style: TextStyle(fontSize: 40)),
            SizedBox(height: 20),
            ElevatedButton(
              // カウンターの値を変更
              onPressed: () =&gt; ref.read(counterProvider.notifier).state++,
              child: Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> counterProvider = </span><span style="color: #4EC9B0">StateProvider</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">int</span><span style="color: #D4D4D4">&gt;((ref) =&gt; </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">HomeScreen</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ConsumerWidget</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">@override</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">Widget</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">build</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">BuildContext</span><span style="color: #D4D4D4"> context, </span><span style="color: #4EC9B0">WidgetRef</span><span style="color: #D4D4D4"> ref) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">// カウンターの値を監視</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> count = ref.</span><span style="color: #DCDCAA">watch</span><span style="color: #D4D4D4">(counterProvider);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Scaffold</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">      appBar: </span><span style="color: #4EC9B0">AppBar</span><span style="color: #D4D4D4">(title: </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Counter Example&#39;</span><span style="color: #D4D4D4">)),</span></span>
<span class="line"><span style="color: #D4D4D4">      body: </span><span style="color: #4EC9B0">Center</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">        child: </span><span style="color: #4EC9B0">Column</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">          mainAxisAlignment: </span><span style="color: #4EC9B0">MainAxisAlignment</span><span style="color: #D4D4D4">.center,</span></span>
<span class="line"><span style="color: #D4D4D4">          children: [</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Count: $</span><span style="color: #9CDCFE">count</span><span style="color: #CE9178">&#39;</span><span style="color: #D4D4D4">, style: </span><span style="color: #4EC9B0">TextStyle</span><span style="color: #D4D4D4">(fontSize: </span><span style="color: #B5CEA8">40</span><span style="color: #D4D4D4">)),</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #4EC9B0">SizedBox</span><span style="color: #D4D4D4">(height: </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #4EC9B0">ElevatedButton</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">              </span><span style="color: #6A9955">// カウンターの値を変更</span></span>
<span class="line"><span style="color: #D4D4D4">              onPressed: () =&gt; ref.</span><span style="color: #DCDCAA">read</span><span style="color: #D4D4D4">(counterProvider.notifier).state++,</span></span>
<span class="line"><span style="color: #D4D4D4">              child: </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Increment&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">            ),</span></span>
<span class="line"><span style="color: #D4D4D4">          ],</span></span>
<span class="line"><span style="color: #D4D4D4">        ),</span></span>
<span class="line"><span style="color: #D4D4D4">      ),</span></span>
<span class="line"><span style="color: #D4D4D4">    );</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">解説</p>



<ul class="wp-block-list">
<li><strong><code>ref.watch(counterProvider)</code></strong>：カウンターの現在の値を取得して監視します。状態が変更されるたびにUIがリビルドされます。</li>



<li><strong><code>ref.read(counterProvider.notifier)</code></strong>：状態を直接操作して変更するために使用します。</li>
</ul>



<h2 class="wp-block-heading">非同期処理と<code>FutureProvider</code></h2>



<p class="wp-block-paragraph">非同期処理を行う場合は、<code>FutureProvider</code>を使います。以下は、APIなどのデータを非同期で取得する例です。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="final dataProvider = FutureProvider&lt;String&gt;((ref) async {
  await Future.delayed(Duration(seconds: 2));
  return 'Hello from Future!';
});

class HomeScreen extends HookWidget {
  @override
  Widget build(BuildContext context) {
    // 非同期データを監視
    final asyncValue = ref.watch(dataProvider);

    return Scaffold(
      appBar: AppBar(title: Text('FutureProvider Example')),
      body: Center(
        child: asyncValue.when(
          data: (value) =&gt; Text(value),
          loading: () =&gt; CircularProgressIndicator(),
          error: (err, stack) =&gt; Text('Error: $err'),
        ),
      ),
    );
  }
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> dataProvider = </span><span style="color: #4EC9B0">FutureProvider</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4">&gt;((ref) </span><span style="color: #C586C0">async</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">await</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Future</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">delayed</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">Duration</span><span style="color: #D4D4D4">(seconds: </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">));</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;Hello from Future!&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">});</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">HomeScreen</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">HookWidget</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">@override</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">Widget</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">build</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">BuildContext</span><span style="color: #D4D4D4"> context) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955">// 非同期データを監視</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> asyncValue = ref.</span><span style="color: #DCDCAA">watch</span><span style="color: #D4D4D4">(dataProvider);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Scaffold</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">      appBar: </span><span style="color: #4EC9B0">AppBar</span><span style="color: #D4D4D4">(title: </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;FutureProvider Example&#39;</span><span style="color: #D4D4D4">)),</span></span>
<span class="line"><span style="color: #D4D4D4">      body: </span><span style="color: #4EC9B0">Center</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">        child: asyncValue.</span><span style="color: #C586C0">when</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">          data: (value) =&gt; </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(value),</span></span>
<span class="line"><span style="color: #D4D4D4">          loading: () =&gt; </span><span style="color: #4EC9B0">CircularProgressIndicator</span><span style="color: #D4D4D4">(),</span></span>
<span class="line"><span style="color: #D4D4D4">          error: (err, stack) =&gt; </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;Error: $</span><span style="color: #9CDCFE">err</span><span style="color: #CE9178">&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">        ),</span></span>
<span class="line"><span style="color: #D4D4D4">      ),</span></span>
<span class="line"><span style="color: #D4D4D4">    );</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">解説</p>



<ul class="wp-block-list">
<li><strong><code>FutureProvider</code></strong>：非同期データを提供するプロバイダで、APIリクエストやデータベース操作などに使われます。</li>



<li><strong><code>asyncValue.when</code></strong>：非同期処理の状態に応じて、データ表示、ローディングインジケーター、エラーメッセージの表示を切り替えます。</li>
</ul>



<h2 class="wp-block-heading">Riverpodのベストプラクティス</h2>



<ol class="wp-block-list">
<li><strong>ProviderScopeを適切に使用</strong>
<ul class="wp-block-list">
<li>すべてのプロバイダは<code>ProviderScope</code>内で管理されるため、これをアプリのルートに配置することで、すべてのプロバイダが適切に管理されます。</li>
</ul>
</li>



<li><strong><code>ref.watch</code>と<code>ref.read</code>の使い分け</strong>
<ul class="wp-block-list">
<li><strong><code>ref.watch</code></strong>：プロバイダの値を監視し、変更があるたびにUIを再レンダリングします。</li>



<li><strong><code>ref.read</code></strong>：値を一度取得するだけ、または値を更新する場合に使います（再レンダリングは行われません）。</li>
</ul>
</li>



<li><strong>非同期データの管理</strong>
<ul class="wp-block-list">
<li><code>FutureProvider</code>や<code>StreamProvider</code>を使って非同期データの状態（ロード中、エラー、成功）を適切に処理することが、ユーザーフレンドリーなUIを提供する鍵です。</li>
</ul>
</li>
</ol>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph"><strong><code>hooks_riverpod</code>を活用することで、Flutterアプリケーションの状態管理が簡単になり、UIロジックがシンプルに記述できます。特に、<code>WidgetRef</code>を使った</strong><code>ref.watch</code><strong>による状態管理は直感的で、プロジェクトの複雑度に応じてスケーラブルに使えます</strong>。この記事を参考に、<code>hooks_riverpod</code>をマスターし、Flutter開発をさらに効率的に行いましょう。</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://techgrowup.net/flutter-hooks-riverpod/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Disk: Enhanced  を使用したページ キャッシュ

Served from: techgrowup.net @ 2026-07-09 00:05:29 by W3 Total Cache
-->