<?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>状態管理</title>
	<atom:link href="https://techgrowup.net/tag/%e7%8a%b6%e6%85%8b%e7%ae%a1%e7%90%86/feed/" rel="self" type="application/rss+xml" />
	<link>https://techgrowup.net</link>
	<description>エンジニアを強くする</description>
	<lastBuildDate>Wed, 30 Apr 2025 22:00:00 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1</generator>

<image>
	<url>https://techgrowup.net/wp-content/uploads/2021/05/hp-icon-150x150.png</url>
	<title>状態管理</title>
	<link>https://techgrowup.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>useReducer完全入門──複雑な状態管理をスマートに解決するReactフックの使い方</title>
		<link>https://techgrowup.net/react-usereducer/</link>
					<comments>https://techgrowup.net/react-usereducer/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[techgrowup]]></dc:creator>
		<pubDate>Wed, 30 Apr 2025 22:00:00 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[dispatch]]></category>
		<category><![CDATA[Reducer]]></category>
		<category><![CDATA[useReducer]]></category>
		<category><![CDATA[コンポーネント設計]]></category>
		<category><![CDATA[状態管理]]></category>
		<guid isPermaLink="false">https://techgrowup.net/?p=2835</guid>

					<description><![CDATA[なぜuseReducerが必要か useStateは直感的で便利ですが、 といった場面では読みづらくなります。こうしたケースでuseReducerを使うと、状態更新ロジックを1カ所に集約でき、コンポーネントがスッキリしま [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">なぜuseReducerが必要か</h2>



<p class="wp-block-paragraph"><code>useState</code>は直感的で便利ですが、</p>



<ul class="wp-block-list">
<li><strong>複数の状態が相互に影響する</strong></li>



<li><strong>更新ロジックが長い if/else で肥大化する</strong></li>



<li><strong>次の状態が前の状態に依存する更新が多い</strong></li>
</ul>



<p class="wp-block-paragraph">といった場面では読みづらくなります。こうしたケースで<code>useReducer</code>を使うと、<strong>状態更新ロジックを1カ所に集約</strong>でき、コンポーネントがスッキリします。</p>



<h2 class="wp-block-heading">基本シグネチャ</h2>



<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="const [state, dispatch] = useReducer(reducer, initialState, init?)" 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">const</span><span style="color: #D4D4D4"> [</span><span style="color: #4FC1FF">state</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">dispatch</span><span style="color: #D4D4D4">] = </span><span style="color: #DCDCAA">useReducer</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">reducer</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">initialState</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">init</span><span style="color: #D4D4D4">?)</span></span></code></pre></div>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th>パラメータ</th><th>型</th><th>意味</th></tr></thead><tbody><tr><td><code>reducer</code></td><td><code>(state, action) ⇒ newState</code></td><td>更新ロジックを持つ純粋関数</td></tr><tr><td><code>initialState</code></td><td>任意</td><td>初期値</td></tr><tr><td><code>init</code></td><td><em>(optional)</em> <code>(arg) ⇒ initializedState</code></td><td>遅延初期化用</td></tr></tbody></table></div></figure>



<p class="wp-block-paragraph">戻り値</p>



<ul class="wp-block-list">
<li><code>state</code>：現在の状態</li>



<li><code>dispatch</code>：アクションを送る関数</li>
</ul>



<h2 class="wp-block-heading">まずはカウンターで理解</h2>



<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 { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment': return { count: state.count + 1 };
    case 'decrement': return { count: state.count - 1 };
    default: throw new Error();
  }
}

export default function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });
  return (
    &lt;&gt;
      &lt;p&gt;Count: {state.count}&lt;/p&gt;
      &lt;button onClick={() =&gt; dispatch({ type: 'increment' })}&gt;＋&lt;/button&gt;
      &lt;button onClick={() =&gt; dispatch({ type: 'decrement' })}&gt;−&lt;/button&gt;
    &lt;/&gt;
  );
}" 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: #C586C0">import</span><span style="color: #D4D4D4"> { </span><span style="color: #9CDCFE">useReducer</span><span style="color: #D4D4D4"> } </span><span style="color: #C586C0">from</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;react&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">reducer</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">action</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">switch</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">action</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">type</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">case</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;increment&#39;</span><span style="color: #D4D4D4">: </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> { </span><span style="color: #9CDCFE">count:</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">count</span><span style="color: #D4D4D4"> + </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> };</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">case</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;decrement&#39;</span><span style="color: #D4D4D4">: </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> { </span><span style="color: #9CDCFE">count:</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">count</span><span style="color: #D4D4D4"> - </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> };</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">default</span><span style="color: #D4D4D4">: </span><span style="color: #C586C0">throw</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">new</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">Error</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: #C586C0">export</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">default</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">Counter</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> [</span><span style="color: #4FC1FF">state</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">dispatch</span><span style="color: #D4D4D4">] = </span><span style="color: #DCDCAA">useReducer</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">reducer</span><span style="color: #D4D4D4">, { </span><span style="color: #9CDCFE">count:</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">0</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>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">p</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">Count: </span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">count</span><span style="color: #569CD6">}</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">p</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">button</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">onClick</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #D4D4D4">() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">dispatch</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">type:</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;increment&#39;</span><span style="color: #D4D4D4"> })</span><span style="color: #569CD6">}</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">＋</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">button</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">button</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">onClick</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #D4D4D4">() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">dispatch</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">type:</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;decrement&#39;</span><span style="color: #D4D4D4"> })</span><span style="color: #569CD6">}</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">−</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">button</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;/&gt;</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"><strong>ポイント解説</strong></p>



<ul class="wp-block-list">
<li><code>reducer</code> は <strong>純粋関数</strong>。副作用を入れない</li>



<li><code>dispatch</code> へは <strong>オブジェクト</strong>を渡す（type必須）</li>



<li>UI 側は state を読むだけ＝ロジックが分離され可読性↑</li>
</ul>



<h2 class="wp-block-heading">複数フィールドのフォーム例</h2>



<p class="wp-block-paragraph"><code>useState</code>でそれぞれ管理すると更新がバラけますが、<code>useReducer</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="function formReducer(state, action) {
  switch (action.type) {
    case 'change':
      return { ...state, [action.field]: action.value };
    case 'reset':
      return action.initial;
    default:
      return state;
  }
}

const initialForm = { name: '', email: '', password: '' };

function SignupForm() {
  const [form, dispatch] = useReducer(formReducer, initialForm);

  const handleChange = e =&gt;
    dispatch({ type: 'change', field: e.target.name, value: e.target.value });

  return (
    &lt;form&gt;
      {Object.entries(form).map(([key, val]) =&gt; (
        &lt;input key={key} name={key} value={val} onChange={handleChange} /&gt;
      ))}
      &lt;button onClick={() =&gt; dispatch({ type: 'reset', initial: initialForm })}&gt;
        クリア
      &lt;/button&gt;
    &lt;/form&gt;
  );
}" 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">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">formReducer</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">action</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">switch</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">action</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">type</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">case</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;change&#39;</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: #9CDCFE">state</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">[action.field]:</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">action</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">value</span><span style="color: #D4D4D4"> };</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">case</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;reset&#39;</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: #9CDCFE">action</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">initial</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">default</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: #9CDCFE">state</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">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">initialForm</span><span style="color: #D4D4D4"> = { </span><span style="color: #9CDCFE">name:</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">email:</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">password:</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;&#39;</span><span style="color: #D4D4D4"> };</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">SignupForm</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> [</span><span style="color: #4FC1FF">form</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">dispatch</span><span style="color: #D4D4D4">] = </span><span style="color: #DCDCAA">useReducer</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">formReducer</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">initialForm</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">handleChange</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">e</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">=&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">dispatch</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">type:</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;change&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">field:</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">e</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">target</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">name</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">value:</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">e</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">target</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">value</span><span style="color: #D4D4D4"> });</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>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">form</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">Object</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">entries</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">form</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">map</span><span style="color: #D4D4D4">(([</span><span style="color: #9CDCFE">key</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">val</span><span style="color: #D4D4D4">]) </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">input</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">key</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">key</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">name</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">key</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">value</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">val</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">onChange</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">handleChange</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      ))</span><span style="color: #569CD6">}</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">button</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">onClick</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #D4D4D4">() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">dispatch</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">type:</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;reset&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">initial:</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">initialForm</span><span style="color: #D4D4D4"> })</span><span style="color: #569CD6">}</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">        クリア</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">button</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">form</span><span style="color: #808080">&gt;</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">深掘り</h3>



<ul class="wp-block-list">
<li><code>...state</code> で既存をコピー＝<strong>不変性</strong>を守る</li>



<li><code>reset</code>アクションでワンアクション全項目初期化</li>



<li>大量フィールドでも reducer が変わらないので拡張に強い</li>
</ul>



<h2 class="wp-block-heading">遅延初期化でパフォーマンス改善</h2>



<p class="wp-block-paragraph">重い計算で初期値を作る場合、第三引数 <code>init</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="function init(countFromLocal) {
  return { count: countFromLocal };
}
const [state, dispatch] = useReducer(reducer, initialArg, init);" 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">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">init</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">countFromLocal</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: #9CDCFE">count:</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">countFromLocal</span><span style="color: #D4D4D4"> };</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> [</span><span style="color: #4FC1FF">state</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">dispatch</span><span style="color: #D4D4D4">] = </span><span style="color: #DCDCAA">useReducer</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">reducer</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">initialArg</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">init</span><span style="color: #D4D4D4">);</span></span></code></pre></div>



<h2 class="wp-block-heading">useState vs useReducer 使い分け指針</h2>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th>シチュエーション</th><th>推奨フック</th></tr></thead><tbody><tr><td>1〜2個の単純な値</td><td><code>useState</code></td></tr><tr><td>更新ロジックが直感的</td><td><code>useState</code></td></tr><tr><td>多数のフィールド・複雑な分岐</td><td><code>useReducer</code></td></tr><tr><td>次の状態が前の状態に強く依存</td><td><code>useReducer</code></td></tr><tr><td>Redux 風のアーキテクチャを局所的に実現</td><td><code>useReducer</code></td></tr></tbody></table></div></figure>



<h2 class="wp-block-heading">コンポーネント分割との相性</h2>



<p class="wp-block-paragraph">Reducer を別ファイルに切り出し、複数コンポーネントから共通利用するとReduxライクな構成が得られます。</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="// todoReducer.js
export function todoReducer(state, action) { /* 省略 */ }

// TodoList.jsx
import { todoReducer } from './todoReducer';
const [todos, dispatch] = useReducer(todoReducer, []);" 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: #6A9955">// todoReducer.js</span></span>
<span class="line"><span style="color: #C586C0">export</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">todoReducer</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">action</span><span style="color: #D4D4D4">) { </span><span style="color: #6A9955">/* 省略 */</span><span style="color: #D4D4D4"> }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">// TodoList.jsx</span></span>
<span class="line"><span style="color: #C586C0">import</span><span style="color: #D4D4D4"> { </span><span style="color: #9CDCFE">todoReducer</span><span style="color: #D4D4D4"> } </span><span style="color: #C586C0">from</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;./todoReducer&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> [</span><span style="color: #4FC1FF">todos</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">dispatch</span><span style="color: #D4D4D4">] = </span><span style="color: #DCDCAA">useReducer</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">todoReducer</span><span style="color: #D4D4D4">, []);</span></span></code></pre></div>



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



<p class="wp-block-paragraph"><code>useReducer</code>は<strong>状態更新ロジックを一元管理</strong>し、可読性と拡張性を両立させる強力なフックです。</p>



<ol class="wp-block-list">
<li>純粋関数 <code>reducer</code> を定義</li>



<li><code>dispatch</code> で明示的にアクションを送る</li>



<li>ステートが複雑化したら <code>useReducer</code> へ移行</li>
</ol>



<p class="wp-block-paragraph">ロジックが整理されることでバグ発生率が減り、大規模アプリでもスケールしやすいコードベースを実現できます。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://techgrowup.net/react-usereducer/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Flutter開発入門11 StatefulWidgetとは</title>
		<link>https://techgrowup.net/flutter-stateful-widget/</link>
					<comments>https://techgrowup.net/flutter-stateful-widget/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[techgrowup]]></dc:creator>
		<pubDate>Mon, 02 Sep 2024 18:54:14 +0000</pubDate>
				<category><![CDATA[Flutter]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Dart]]></category>
		<category><![CDATA[StatefulWidget]]></category>
		<category><![CDATA[アプリ開発]]></category>
		<category><![CDATA[状態管理]]></category>
		<guid isPermaLink="false">https://techgrowup.net/?p=1746</guid>

					<description><![CDATA[はじめに 　Flutterを使ってアプリケーションを開発する際、ユーザーの操作やデータの変更に応じてUIが変化するコンポーネントを作成する必要があります。そのために使われるのがStatefulWidgetです。本記事では [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">はじめに</h1>



<p class="wp-block-paragraph">　Flutterを使ってアプリケーションを開発する際、ユーザーの操作やデータの変更に応じてUIが変化するコンポーネントを作成する必要があります。そのために使われるのが<code>StatefulWidget</code>です。本記事では、<code>StatefulWidget</code>の基本的な使い方や実際の活用方法について、わかりやすく解説します。</p>



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



<p class="wp-block-paragraph">　<code>StatefulWidget</code>は、Flutterにおける状態を持つウィジェットです。<code>StatelessWidget</code>と異なり、<code>StatefulWidget</code>はその状態が変わるたびに再描画され、動的なUIを提供します。たとえば、ボタンを押すとテキストが変わる、フォームに入力するたびに内容が更新されるといったシナリオで使用されます。</p>



<h3 class="wp-block-heading">StatefulWidgetの基本構造</h3>



<p class="wp-block-paragraph">　<code>StatefulWidget</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/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('StatefulWidget Example'),
        ),
        body: Center(
          child: MyStatefulWidget(),
        ),
      ),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  @override
  _MyStatefulWidgetState createState() =&gt; _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State&lt;MyStatefulWidget&gt; {
  String _displayText = 'Hello, Tech Grow Up!';

  void _updateText() {
    setState(() {
      _displayText = 'ボタンが押された!';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text(
          _displayText,
          style: const TextStyle(fontSize: 24),
        ),
        const SizedBox(height: 20),
        ElevatedButton(
          onPressed: _updateText,
          child: const Text('押してね'),
        ),
      ],
    );
  }
}" 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/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">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">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">(</span></span>
<span class="line"><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;StatefulWidget Example&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><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">MyStatefulWidget</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>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">MyStatefulWidget</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">StatefulWidget</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">_MyStatefulWidgetState</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">createState</span><span style="color: #D4D4D4">() =&gt; </span><span style="color: #4EC9B0">_MyStatefulWidgetState</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">_MyStatefulWidgetState</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">State</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">MyStatefulWidget</span><span style="color: #D4D4D4">&gt; {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4"> _displayText = </span><span style="color: #CE9178">&#39;Hello, Tech Grow Up!&#39;</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">_updateText</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">setState</span><span style="color: #D4D4D4">(() {</span></span>
<span class="line"><span style="color: #D4D4D4">      _displayText = </span><span style="color: #CE9178">&#39;ボタンが押された!&#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>
<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">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>
<span class="line"><span style="color: #D4D4D4">          _displayText,</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">24</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 style="color: #569CD6">const</span><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">          onPressed: _updateText,</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;押してね&#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>



<h3 class="wp-block-heading">解説</h3>



<ul class="wp-block-list">
<li><strong><code>MyApp</code>クラス</strong>: <code>MaterialApp</code>と<code>Scaffold</code>を使って基本的なアプリケーション構造を定義します。</li>



<li><strong><code>MyStatefulWidget</code>クラス</strong>: <code>StatefulWidget</code>を継承したウィジェットです。このウィジェットは状態を持ち、ユーザーの操作に応じてUIが変化します。</li>



<li><strong><code>_MyStatefulWidgetState</code>クラス</strong>: ここで状態（<code>_displayText</code>）を定義し、<code>setState</code>メソッドを使って状態を更新します。ボタンが押されるとテキストが変わる仕組みです。</li>
</ul>



<p class="wp-block-paragraph">この例では、ボタンを押すと表示されるテキストが「ボタンが押された!」に変わります。<code>StatefulWidget</code>を使うことで、ユーザーの操作に応じて動的にUIを変更することが可能です。</p>



<figure class="wp-block-embed aligncenter is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="flutter stateful video" width="1256" height="707" src="https://www.youtube.com/embed/1DALRjLHYw0?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h2 class="wp-block-heading">StatefulWidgetの活用シーン</h2>



<p class="wp-block-paragraph">　<code>StatefulWidget</code>は、次のようなシーンで役立ちます。</p>



<ol class="wp-block-list">
<li><strong>ユーザー入力の管理</strong>: フォームやチェックボックス、スライダーなど、ユーザーの入力や選択に応じてUIが変わる要素を管理するために使用します。</li>



<li><strong>アニメーション</strong>: アニメーションの状態管理や、時間経過に応じて変化するUIを実現するために活用されます。</li>



<li><strong>カウンターやインクリメント</strong>: ボタンをクリックして数値を増やすようなインタラクティブな要素に最適です。</li>



<li><strong>タブやページナビゲーション</strong>: 複数のページやタブを持つアプリケーションで、ユーザーの操作に応じて状態を保持し、ページ間のデータを管理します。</li>
</ol>



<h2 class="wp-block-heading">StatefulWidgetのメリットと注意点</h2>



<h3 class="wp-block-heading">メリット</h3>



<ul class="wp-block-list">
<li><strong>動的なUIの実現</strong>: ユーザーの操作やデータの変更に応じて、リアルタイムにUIを更新できるため、インタラクティブなアプリケーションを構築するのに最適です。</li>



<li><strong>状態管理の簡便さ</strong>: <code>StatefulWidget</code>は、内部で状態を管理するため、UIの一部だけを効率的に更新することができます。</li>
</ul>



<h3 class="wp-block-heading">注意点</h3>



<ul class="wp-block-list">
<li><strong>パフォーマンスに注意</strong>: 状態が頻繁に変わる複雑なウィジェットツリーを持つアプリケーションでは、適切に<code>setState</code>を管理しないとパフォーマンスが低下する可能性があります。</li>



<li><strong>状態のリセット</strong>: <code>StatefulWidget</code>の状態がリセットされることがあり、アプリケーションの設計によっては意図しない動作を引き起こすことがあります。そのため、状態の管理方法には注意が必要です。</li>
</ul>



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



<p class="wp-block-paragraph">　<code>StatefulWidget</code>は、Flutterで動的なUIコンポーネントを作成する際に欠かせないクラスです。状態を持たないシンプルな<code>StatelessWidget</code>とは異なり、<code>StatefulWidget</code>はユーザーの操作やデータの変化に応じてUIをリアルタイムに更新することができます。Flutterアプリの中でインタラクティブな要素を作成したい場合、<code>StatefulWidget</code>を効果的に活用することが成功への鍵となります。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://techgrowup.net/flutter-stateful-widget/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Flutter開発入門10 StatelessWidgetとは</title>
		<link>https://techgrowup.net/flutter-stateless-widget/</link>
					<comments>https://techgrowup.net/flutter-stateless-widget/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[techgrowup]]></dc:creator>
		<pubDate>Sun, 01 Sep 2024 20:16:20 +0000</pubDate>
				<category><![CDATA[Flutter]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Dart]]></category>
		<category><![CDATA[StatelessWidget]]></category>
		<category><![CDATA[アプリ開発]]></category>
		<category><![CDATA[状態管理]]></category>
		<guid isPermaLink="false">https://techgrowup.net/?p=1741</guid>

					<description><![CDATA[はじめに 　FlutterでUIを構築する際、まず理解しておくべき重要なコンポーネントがStatelessWidgetです。StatelessWidgetは、状態を持たないWidgetを作成するために使用されます。本記事 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">はじめに</h1>



<p class="wp-block-paragraph">　FlutterでUIを構築する際、まず理解しておくべき重要なコンポーネントが<code>StatelessWidget</code>です。<code>StatelessWidget</code>は、状態を持たないWidgetを作成するために使用されます。本記事では、<code>StatelessWidget</code>の基本的な使い方と、その役割について詳しく解説します。前回のFlutter入門開発はこちらです。</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-inherited-widget/" title="Flutter開発入門9 InheritedWidgetについて" 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/08/flutter-inherited-widget-icatch-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://techgrowup.net/wp-content/uploads/2024/08/flutter-inherited-widget-icatch-160x90.webp 160w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-inherited-widget-icatch-1024x585.webp 1024w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-inherited-widget-icatch-768x439.webp 768w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-inherited-widget-icatch-120x68.webp 120w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-inherited-widget-icatch-320x180.webp 320w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-inherited-widget-icatch-376x212.webp 376w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-inherited-widget-icatch.webp 1200w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">Flutter開発入門9 InheritedWidgetについて</div><div class="blogcard-snippet internal-blogcard-snippet">FlutterのInheritedWidgetを使った状態管理の基本を学びましょう。効率的なデータの伝達方法や具体的な活用シーンをわかりやすく解説。初心者から上級者まで役立つ情報を提供します。</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.09.01</div></div></div></div></a>
</div></figure>



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



<p class="wp-block-paragraph">　<code>StatelessWidget</code>は、その名の通り「状態（state）」を持たないウィジェットです。表示される内容が一度決まると、その内容が変化しないため、再描画や再構築が必要ないシンプルなUIコンポーネントに使用されます。</p>



<p class="wp-block-paragraph">　例えば、テキストや画像を表示するためのWidgetは、ユーザーの操作に応じて変化する必要がないため、<code>StatelessWidget</code>として実装されることが一般的です。</p>



<h3 class="wp-block-heading">StatelessWidgetの基本構造</h3>



<p class="wp-block-paragraph"><code>StatelessWidget</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/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('StatelessWidget Example'),
        ),
        body: Center(
          child: MyStatelessWidget(),
        ),
      ),
    );
  }
}

class MyStatelessWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return const Text(
      'Hello, Tech Grow Up!',
      style: TextStyle(fontSize: 24, color: Colors.blue),
    );
  }
}" 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/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">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">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">(</span></span>
<span class="line"><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;StatelessWidget Example&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><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">MyStatelessWidget</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>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">MyStatelessWidget</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: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #CE9178">&#39;Hello, Tech Grow Up!&#39;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">      style: </span><span style="color: #4EC9B0">TextStyle</span><span style="color: #D4D4D4">(fontSize: </span><span style="color: #B5CEA8">24</span><span style="color: #D4D4D4">, color: </span><span style="color: #4EC9B0">Colors</span><span style="color: #D4D4D4">.blue),</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">解説</h3>



<ul class="wp-block-list">
<li><strong><code>MyApp</code>クラス</strong>: <code>StatelessWidget</code>を使って、アプリ全体の構成を定義しています。<code>MaterialApp</code>をルートとして、<code>Scaffold</code>で基本的なアプリケーションレイアウトを提供します。</li>



<li><strong><code>MyStatelessWidget</code>クラス</strong>: このクラスが<code>StatelessWidget</code>の具体的な実装部分です。<code>build</code>メソッド内で、テキストウィジェットを表示するだけのシンプルなUIを構築しています。</li>
</ul>



<p class="wp-block-paragraph">　この例では、画面中央に「Hello, Tech Grow Up!」というテキストが青色で表示されます。テキストや色のプロパティは固定されており、ユーザーの操作によって変化しません。</p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="360" height="800" src="https://techgrowup.net/wp-content/uploads/2024/08/flutter-stateless-widget.webp" alt="" class="wp-image-1743" srcset="https://techgrowup.net/wp-content/uploads/2024/08/flutter-stateless-widget.webp 360w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-stateless-widget-135x300.webp 135w" sizes="(max-width: 360px) 100vw, 360px" /></figure>



<h2 class="wp-block-heading">StatelessWidgetの活用シーン</h2>



<p class="wp-block-paragraph">　<code>StatelessWidget</code>は、以下のようなシーンで効果的に活用されます。</p>



<ul class="wp-block-list">
<li><strong>シンプルなUI要素の作成</strong>: 複雑な状態管理が不要な場合、<code>StatelessWidget</code>を使うことで、コードをシンプルに保つことができます。</li>



<li><strong>静的コンテンツの表示</strong>: テキスト、画像、アイコンなど、ユーザーの操作に応じて変化しないコンテンツの表示に適しています。</li>



<li><strong>デザインの再利用</strong>: 繰り返し使用される固定のレイアウトやスタイルを、<code>StatelessWidget</code>としてまとめることで、コードの再利用性を高めることができます。</li>
</ul>



<h2 class="wp-block-heading">StatefulWidgetとの違い</h2>



<p class="wp-block-paragraph">　<code>StatelessWidget</code>が「状態を持たない」ウィジェットであるのに対して、<code>StatefulWidget</code>は「状態を持つ」ウィジェットです。<code>StatefulWidget</code>では、ユーザーの操作やデータの変更に応じてUIが再構築されるため、インタラクティブなコンポーネントに使用されます。</p>



<p class="wp-block-paragraph">　例えば、ボタンをクリックした際に表示される内容が変わる場合や、チェックボックスの状態が変わる場合は、<code>StatefulWidget</code>を使用します。</p>



<h2 class="wp-block-heading"><code>StatelessWidget</code>を選ぶべき場合</h2>



<ul class="wp-block-list">
<li><strong>固定されたデータの表示</strong>: 一度表示されたら変わらないデータ（例：記事の見出し、ロゴ、ラベル）を表示する場合。</li>



<li><strong>単純なデザインの再利用</strong>: 複雑なロジックを含まないUIパーツを再利用する場合。</li>
</ul>



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



<p class="wp-block-paragraph">　<code>StatelessWidget</code>は、シンプルで軽量なUIコンポーネントを作成するために不可欠なクラスです。状態管理が不要な部分では、<code>StatelessWidget</code>を活用することで、コードの保守性とパフォーマンスを向上させることができます。Flutterを始めたばかりの方も、まずはこの<code>StatelessWidget</code>から学び、その後で状態を持つ<code>StatefulWidget</code>を学ぶと良いでしょう。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://techgrowup.net/flutter-stateless-widget/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Flutter開発入門9 InheritedWidgetについて</title>
		<link>https://techgrowup.net/flutter-inherited-widget/</link>
					<comments>https://techgrowup.net/flutter-inherited-widget/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[techgrowup]]></dc:creator>
		<pubDate>Sat, 31 Aug 2024 16:57:35 +0000</pubDate>
				<category><![CDATA[Flutter]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Dart]]></category>
		<category><![CDATA[InheritedWidget]]></category>
		<category><![CDATA[アプリ開発]]></category>
		<category><![CDATA[状態管理]]></category>
		<guid isPermaLink="false">https://techgrowup.net/?p=1737</guid>

					<description><![CDATA[はじめに 　Flutterでは、状態管理はアプリケーションの核心部分を担う重要な要素です。その中でもInheritedWidgetは、ツリー内のWidget間でデータを効率よく共有するための基本的な仕組みとして広く使われ [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">はじめに</h1>



<p class="wp-block-paragraph">　Flutterでは、状態管理はアプリケーションの核心部分を担う重要な要素です。その中でも<code>InheritedWidget</code>は、ツリー内のWidget間でデータを効率よく共有するための基本的な仕組みとして広く使われています。本記事では、<code>InheritedWidget</code>の基本的な役割と、その使い方について解説します。前回のFlutter入門開発はこちらです。</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-widget/" title="Flutter開発入門8 主要なWidgetについて" 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 loading="lazy" decoding="async" width="160" height="90" src="https://techgrowup.net/wp-content/uploads/2024/08/flutter-widget-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://techgrowup.net/wp-content/uploads/2024/08/flutter-widget-160x90.webp 160w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-widget-1024x585.webp 1024w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-widget-768x439.webp 768w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-widget-120x68.webp 120w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-widget-320x180.webp 320w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-widget-376x212.webp 376w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-widget.webp 1200w" sizes="(max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">Flutter開発入門8 主要なWidgetについて</div><div class="blogcard-snippet internal-blogcard-snippet">FlutterでUIを構築するために欠かせない基本Widgetを徹底解説。Text、Image、Button、Container、ListViewなど、よく使うWidgetの使い方とサンプルコードを分かりやすく紹介します。これからFlutterを学ぶ方必見のガイドです。</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 loading="lazy" 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.09.01</div></div></div></div></a>
</div></figure>



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



<p class="wp-block-paragraph">　<code>InheritedWidget</code>は、Flutterのウィジェットツリー内で親から子にデータを効率よく伝達するために使用される特殊なWidgetです。通常、アプリケーションの状態（ステート）は上位のWidgetで管理され、それをツリー内の複数の子Widgetで共有する必要があります。このとき、<code>InheritedWidget</code>を活用することで、効率的かつ簡潔にデータを渡すことが可能になります。</p>



<h3 class="wp-block-heading">InheritedWidgetの基本構造</h3>



<p class="wp-block-paragraph">　<code>InheritedWidget</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/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('InheritedWidget Example')),
        body: MyInheritedWidget(
          data: 'Hello, Tech Grow Up!',
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              TextWidget(),
            ],
          ),
        ),
      ),
    );
  }
}

class MyInheritedWidget extends InheritedWidget {
  final String data;

  MyInheritedWidget({required this.data, required Widget child})
      : super(child: child);

  @override
  bool updateShouldNotify(MyInheritedWidget oldWidget) {
    return oldWidget.data != data;
  }

  static MyInheritedWidget? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType&lt;MyInheritedWidget&gt;();
  }
}

class TextWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final inheritedWidget = MyInheritedWidget.of(context);
    return Center(
      child: Text(
        inheritedWidget?.data ?? 'No data found',
        style: const TextStyle(fontSize: 24),
      ),
    );
  }
}" 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/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">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">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;InheritedWidget Example&#39;</span><span style="color: #D4D4D4">)),</span></span>
<span class="line"><span style="color: #D4D4D4">        body: </span><span style="color: #4EC9B0">MyInheritedWidget</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">          data: </span><span style="color: #CE9178">&#39;Hello, Tech Grow Up!&#39;</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">TextWidget</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>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">MyInheritedWidget</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">InheritedWidget</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4"> data;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">MyInheritedWidget</span><span style="color: #D4D4D4">({</span><span style="color: #569CD6">required</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">this</span><span style="color: #D4D4D4">.data, </span><span style="color: #569CD6">required</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Widget</span><span style="color: #D4D4D4"> child})</span></span>
<span class="line"><span style="color: #D4D4D4">      : </span><span style="color: #569CD6">super</span><span style="color: #D4D4D4">(child: child);</span></span>
<span class="line"></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">bool</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">updateShouldNotify</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">MyInheritedWidget</span><span style="color: #D4D4D4"> oldWidget) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> oldWidget.data != data;</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">MyInheritedWidget</span><span style="color: #D4D4D4">? </span><span style="color: #DCDCAA">of</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"> context.</span><span style="color: #DCDCAA">dependOnInheritedWidgetOfExactType</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">MyInheritedWidget</span><span style="color: #D4D4D4">&gt;();</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">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">TextWidget</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: #569CD6">final</span><span style="color: #D4D4D4"> inheritedWidget = </span><span style="color: #4EC9B0">MyInheritedWidget</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">of</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">Center</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">      child: </span><span style="color: #4EC9B0">Text</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">        inheritedWidget?.data ?? </span><span style="color: #CE9178">&#39;No data found&#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">24</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></code></pre></div>



<h3 class="wp-block-heading">解説</h3>



<ul class="wp-block-list">
<li><strong><code>MyInheritedWidget</code>クラス</strong>: ここでは、<code>InheritedWidget</code>を継承してカスタムウィジェットを作成しています。<code>data</code>フィールドに保持される値を、ツリー内の子Widgetに伝達します。</li>



<li><strong><code>updateShouldNotify</code>メソッド</strong>: これは、ウィジェットが更新されるかどうかを決定するためのメソッドです。ここでは、新しいデータが古いデータと異なる場合に<code>true</code>を返すようにしています。</li>



<li><strong><code>of</code>メソッド</strong>: <code>MyInheritedWidget</code>のインスタンスをツリー内で取得するための静的メソッドです。このメソッドを使って、子Widgetはデータを取得します。</li>



<li><strong><code>TextWidget</code>クラス</strong>: <code>of</code>メソッドを使用して、<code>InheritedWidget</code>からデータを取得し、それを表示しています。</li>
</ul>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="360" height="800" src="https://techgrowup.net/wp-content/uploads/2024/08/flutter-inherited-widget.webp" alt="" class="wp-image-1738" srcset="https://techgrowup.net/wp-content/uploads/2024/08/flutter-inherited-widget.webp 360w, https://techgrowup.net/wp-content/uploads/2024/08/flutter-inherited-widget-135x300.webp 135w" sizes="(max-width: 360px) 100vw, 360px" /></figure>



<h2 class="wp-block-heading">InheritedWidgetの活用シーン</h2>



<p class="wp-block-paragraph">　<code>InheritedWidget</code>は、以下のようなシーンで効果的に活用できます。</p>



<ol class="wp-block-list">
<li><strong>テーマの管理</strong>: アプリ全体で使用されるテーマデータ（例：カラーやフォント）を一元管理するために、<code>InheritedWidget</code>を使って、全ての子Widgetにテーマデータを伝達します。</li>



<li><strong>ローカライズ</strong>: 多言語対応アプリで、ユーザーが選択した言語に基づいて文字列を表示する場合、<code>InheritedWidget</code>を使用して、選択された言語のデータをツリー全体に伝達します。</li>



<li><strong>アプリ全体の設定</strong>: ユーザーの設定（例：ダークモードのオン/オフ）をアプリ全体に反映させるために、<code>InheritedWidget</code>を使用します。</li>
</ol>



<h2 class="wp-block-heading">InheritedWidgetのメリットと注意点</h2>



<h3 class="wp-block-heading">メリット</h3>



<ul class="wp-block-list">
<li><strong>シンプルなコード構成</strong>: アプリケーション全体でデータを共有するためのコードがシンプルで読みやすくなります。</li>



<li><strong>効率的なデータ伝達</strong>: <code>InheritedWidget</code>を使用することで、ツリーの特定の部分だけに必要なデータを渡すことができ、無駄な再レンダリングを防げます。</li>
</ul>



<h3 class="wp-block-heading">注意点</h3>



<ul class="wp-block-list">
<li><strong>再レンダリングの管理</strong>: <code>updateShouldNotify</code>メソッドの実装に注意しないと、不要な再レンダリングが発生する可能性があります。これにより、パフォーマンスが低下する場合があります。</li>



<li><strong>他の状態管理と比較したシンプルさ</strong>: <code>InheritedWidget</code>はシンプルですが、大規模なアプリケーションでは、<code>Provider</code>や<code>Riverpod</code>など、より高度な状態管理ソリューションが適している場合があります。</li>
</ul>



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



<p class="wp-block-paragraph">　<code>InheritedWidget</code>は、Flutterにおける状態管理の基本を学ぶ上で非常に重要なコンポーネントです。簡単なアプリケーションであれば、このウィジェットを活用することで、効率的かつシンプルに状態管理を行うことができます。Flutterの状態管理に慣れていない方は、まず<code>InheritedWidget</code>から学び、その後他の状態管理パッケージへと進んでいくと良いでしょう。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://techgrowup.net/flutter-inherited-widget/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
