<?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>State</title>
	<atom:link href="https://techgrowup.net/tag/state/feed/" rel="self" type="application/rss+xml" />
	<link>https://techgrowup.net</link>
	<description>エンジニアを強くする</description>
	<lastBuildDate>Sun, 27 Apr 2025 20:00:00 +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>State</title>
	<link>https://techgrowup.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>React.Component徹底ガイド──クラスコンポーネントの基本からライフサイクル・State管理・最適化まで</title>
		<link>https://techgrowup.net/react-class-component/</link>
					<comments>https://techgrowup.net/react-class-component/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[techgrowup]]></dc:creator>
		<pubDate>Sun, 27 Apr 2025 20:00:00 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Component]]></category>
		<category><![CDATA[componentDidMount]]></category>
		<category><![CDATA[Props]]></category>
		<category><![CDATA[setState]]></category>
		<category><![CDATA[shouldComponentUpdate]]></category>
		<category><![CDATA[State]]></category>
		<category><![CDATA[クラスコンポーネント]]></category>
		<category><![CDATA[ライフサイクル]]></category>
		<guid isPermaLink="false">https://techgrowup.net/?p=2824</guid>

					<description><![CDATA[はじめに Reactのコンポーネントは関数コンポーネントが主流になっていますが、クラスベースのReact.Componentも依然として理解しておく価値があります。特に既存の大規模プロジェクトやError Boundar [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">はじめに</h1>



<p class="wp-block-paragraph">Reactのコンポーネントは関数コンポーネントが主流になっていますが、クラスベースの<code>React.Component</code>も依然として理解しておく価値があります。特に既存の大規模プロジェクトやError Boundary（エラーバウンダリ）実装にはクラスコンポーネントが欠かせません。提供する機能を１つずつ丁寧に見ていきましょう。</p>



<h2 class="wp-block-heading">React.Componentとは</h2>



<p class="wp-block-paragraph"><code>React.Component</code> は、ユーザー定義のクラスコンポーネントが継承する基底クラスです。内部では以下を提供します。</p>



<ul class="wp-block-list">
<li><strong><code>props</code></strong>：親から渡される読み取り専用データ</li>



<li><strong><code>state</code></strong>：コンポーネント内部で変化する値</li>



<li><strong><code>render()</code></strong>：UIの描画を司る必須メソッド</li>



<li><strong>ライフサイクルメソッド</strong>：マウント・更新・アンマウント時のフック</li>



<li><strong><code>setState()</code></strong>：<code>state</code>更新と再レンダーのトリガー</li>



<li><strong>エラーバウンダリ</strong>：<code>static getDerivedStateFromError</code> / <code>componentDidCatch</code></li>
</ul>



<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 React from 'react';

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }
  render() {
    return &lt;div&gt;カウント: {this.state.count}&lt;/div&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">React</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">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">MyComponent</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">React</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">Component</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">constructor</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">props</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">super</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">props</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">this</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">0</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: #DCDCAA">render</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: #808080">&lt;</span><span style="color: #569CD6">div</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">カウント: </span><span style="color: #569CD6">{this</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: #569CD6">}</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">div</span><span style="color: #808080">&gt;</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></code></pre></div>



<h2 class="wp-block-heading">propsの扱い</h2>



<p class="wp-block-paragraph"><code>this.props</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="class Greeting extends React.Component {
  render() {
    return &lt;h1&gt;こんにちは、{this.props.name}さん！&lt;/h1&gt;;
  }
}

// 呼び出し側
&lt;Greeting name=&quot;太郎&quot; /&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">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Greeting</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">React</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">Component</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">render</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: #808080">&lt;</span><span style="color: #569CD6">h1</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">こんにちは、</span><span style="color: #569CD6">{this</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">props</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">name</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4">さん！</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">h1</span><span style="color: #808080">&gt;</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: #6A9955">// 呼び出し側</span></span>
<span class="line"><span style="color: #808080">&lt;</span><span style="color: #4EC9B0">Greeting</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">name</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;太郎&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span></span></code></pre></div>



<ul class="wp-block-list">
<li><strong>型注釈</strong>：PropTypes で型・必須チェックを行う例も多い</li>



<li><strong>デフォルトProps</strong>：<code>MyComponent.defaultProps = { count: 10 };</code></li>
</ul>



<h2 class="wp-block-heading">stateとsetState</h2>



<p class="wp-block-paragraph"><code>state</code> はコンポーネントの内部情報を保持し、<code>setState</code> で更新します。<code>setState</code> は<strong>非同期バッチ</strong>処理されるため注意が必要です。</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="class Counter extends React.Component {
  state = { count: 0 };

  handleClick = () =&gt; {
    this.setState({ count: this.state.count + 1 });
    // 複数回連続呼び出すと反映タイミングがずれる可能性あり
  }

  render() {
    return &lt;button onClick={this.handleClick}&gt;{this.state.count}&lt;/button&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">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Counter</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">React</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">Component</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><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">0</span><span style="color: #D4D4D4"> };</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">handleClick</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: #569CD6">this</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">setState</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">count:</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">this</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: #6A9955">// 複数回連続呼び出すと反映タイミングがずれる可能性あり</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: #DCDCAA">render</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: #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">{this</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">handleClick</span><span style="color: #569CD6">}</span><span style="color: #808080">&gt;</span><span style="color: #569CD6">{this</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: #569CD6">}</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">button</span><span style="color: #808080">&gt;</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></code></pre></div>



<ul class="wp-block-list">
<li><strong>関数型更新</strong>：前回のstateを確実に利用したい場合</li>
</ul>



<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="this.setState(prev =&gt; ({ count: prev.count + 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">this</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">setState</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">prev</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> ({ </span><span style="color: #9CDCFE">count:</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">prev</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></code></pre></div>



<ul class="wp-block-list">
<li><strong>マージ</strong>：オブジェクトをマージする形で更新される</li>
</ul>



<h2 class="wp-block-heading">ライフサイクルメソッド一覧</h2>



<p class="wp-block-paragraph">クラスコンポーネントは以下のメソッドをオーバーライドできます。</p>



<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>マウント前</td><td><code>static getDerivedStateFromProps(props, state)</code></td><td>Propsからstateを生成（副作用禁止）</td></tr><tr><td>マウント後</td><td><code>componentDidMount()</code></td><td>API呼び出しやDOM操作を実行</td></tr><tr><td>更新判定</td><td><code>shouldComponentUpdate(nextProps, nextState)</code></td><td>レンダーをスキップする判断</td></tr><tr><td>更新前</td><td><code>getSnapshotBeforeUpdate(prevProps, prevState)</code></td><td>更新前のDOM情報を取得（返却値は次の<code>componentDidUpdate</code>に渡る）</td></tr><tr><td>更新後</td><td><code>componentDidUpdate(prevProps, prevState, snapshot)</code></td><td>更新後に副作用を実行</td></tr><tr><td>アンマウント前</td><td><code>componentWillUnmount()</code></td><td>タイマー解除、購読解除などのクリーンアップ</td></tr><tr><td>エラー処理</td><td><code>static getDerivedStateFromError(error)</code></td><td>エラー発生時にstateを更新</td></tr><tr><td></td><td><code>componentDidCatch(error, info)</code></td><td>UIエラーのログ送信など</td></tr></tbody></table></div></figure>



<h3 class="wp-block-heading">例：データフェッチ</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 DataFetcher extends React.Component {
  state = { data: null };

  componentDidMount() {
    fetch(this.props.url)
      .then(r =&gt; r.json())
      .then(json =&gt; this.setState({ data: json }));
  }

  render() {
    return this.state.data
      ? &lt;div&gt;{this.state.data.title}&lt;/div&gt;
      : &lt;p&gt;読み込み中…&lt;/p&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">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">DataFetcher</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">React</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">Component</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4"> = { </span><span style="color: #9CDCFE">data:</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4"> };</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">componentDidMount</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">fetch</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">this</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">props</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">url</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">      .</span><span style="color: #DCDCAA">then</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">r</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">r</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">json</span><span style="color: #D4D4D4">())</span></span>
<span class="line"><span style="color: #D4D4D4">      .</span><span style="color: #DCDCAA">then</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">json</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">this</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">setState</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">data:</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">json</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: #D4D4D4">  </span><span style="color: #DCDCAA">render</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: #569CD6">this</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">data</span></span>
<span class="line"><span style="color: #D4D4D4">      ? </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">div</span><span style="color: #808080">&gt;</span><span style="color: #569CD6">{this</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">data</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">title</span><span style="color: #569CD6">}</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">div</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">p</span><span style="color: #808080">&gt;</span><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">;</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<h2 class="wp-block-heading">Error Boundary（エラーバウンダリ）</h2>



<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="class ErrorBoundary extends React.Component {
  state = { hasError: false };

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    logErrorToService(error, info);
  }

  render() {
    if (this.state.hasError) {
      return &lt;h2&gt;エラーが発生しました&lt;/h2&gt;;
    }
    return this.props.children;
  }
}" 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">ErrorBoundary</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">React</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">Component</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4"> = { </span><span style="color: #9CDCFE">hasError:</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">false</span><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: #DCDCAA">getDerivedStateFromError</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">hasError:</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">true</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: #D4D4D4">  </span><span style="color: #DCDCAA">componentDidCatch</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">error</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">info</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">logErrorToService</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">error</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">info</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: #D4D4D4">  </span><span style="color: #DCDCAA">render</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (</span><span style="color: #569CD6">this</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">state</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">hasError</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: #808080">&lt;</span><span style="color: #569CD6">h2</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">エラーが発生しました</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">h2</span><span style="color: #808080">&gt;</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: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">this</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">props</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">children</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></code></pre></div>



<ul class="wp-block-list">
<li><strong>再起動</strong>：Error Boundaryをリセットするロジックを外部から制御可能</li>



<li><strong>注意</strong>：副作用フックの代替ではない</li>
</ul>



<h2 class="wp-block-heading">コンテキストとの連携</h2>



<p class="wp-block-paragraph"><code>static contextType = MyContext</code> をクラスに指定すると <code>this.context</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="MyComponent.contextType = ThemeContext;
class MyComponent extends React.Component {
  render() {
    return &lt;div style={{ color: this.context.primary }}&gt;…&lt;/div&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: #9CDCFE">MyComponent</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">contextType</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">ThemeContext</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">MyComponent</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">React</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">Component</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">render</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: #808080">&lt;</span><span style="color: #569CD6">div</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">style</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #D4D4D4">{ </span><span style="color: #9CDCFE">color:</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">this</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">context</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">primary</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">div</span><span style="color: #808080">&gt;</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></code></pre></div>



<h2 class="wp-block-heading">パフォーマンス最適化</h2>



<h3 class="wp-block-heading">shouldComponentUpdate</h3>



<p class="wp-block-paragraph">再レンダーを制御し、不要な<code>render()</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="class PureCounter extends React.Component {
  shouldComponentUpdate(nextProps) {
    return nextProps.value !== this.props.value;
  }
  render() { /* … */ }
}" 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">PureCounter</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">React</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">Component</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">shouldComponentUpdate</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">nextProps</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">nextProps</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">value</span><span style="color: #D4D4D4"> !== </span><span style="color: #569CD6">this</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">props</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>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">render</span><span style="color: #D4D4D4">() { </span><span style="color: #6A9955">/* … */</span><span style="color: #D4D4D4"> }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<h3 class="wp-block-heading">PureComponent</h3>



<p class="wp-block-paragraph"><code>React.PureComponent</code> を継承すると自動的に shallow 比較で <code>shouldComponentUpdate</code> を実装します。</p>



<h2 class="wp-block-heading">メソッドのバインディング</h2>



<p class="wp-block-paragraph"><code>this</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="// コンストラクタ内で
constructor(props) {
  super(props);
  this.handleClick = this.handleClick.bind(this);
}

// クラスフィールド
handleClick = () =&gt; { /* this が正しい */ }" 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">// コンストラクタ内で</span></span>
<span class="line"><span style="color: #DCDCAA">constructor</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">props</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">super</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">props</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">this</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">handleClick</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">this</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">handleClick</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">bind</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">this</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: #6A9955">// クラスフィールド</span></span>
<span class="line"><span style="color: #DCDCAA">handleClick</span><span style="color: #D4D4D4"> = () </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> { </span><span style="color: #6A9955">/* this が正しい */</span><span style="color: #D4D4D4"> }</span></span></code></pre></div>



<h2 class="wp-block-heading">デフォルトPropsとdisplayName</h2>



<ul class="wp-block-list">
<li><strong>defaultProps</strong></li>
</ul>



<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="MyComponent.defaultProps = { 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: #9CDCFE">MyComponent</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">defaultProps</span><span style="color: #D4D4D4"> = { </span><span style="color: #9CDCFE">text:</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;デフォルトテキスト&#39;</span><span style="color: #D4D4D4"> };</span></span></code></pre></div>



<ul class="wp-block-list">
<li><strong>displayName</strong>
<ul class="wp-block-list">
<li>デバッグ時の表示名を変更できます。</li>
</ul>
</li>
</ul>



<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="MyComponent.displayName = 'カスタム名';" 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: #9CDCFE">MyComponent</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">displayName</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&#39;カスタム名&#39;</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



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



<p class="wp-block-paragraph"><code>React.Component</code> を理解すると、既存のクラスコンポーネントやError Boundaryが読み書きできるようになります。ライフサイクルメソッド、<code>state</code> / <code>props</code>、パフォーマンス最適化パターンなどを活用し、堅牢で読みやすいUIコンポーネントを実装しましょう。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://techgrowup.net/react-class-component/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Reactコンポーネント徹底ガイド──基本から応用パターンまでわかりやすく解説</title>
		<link>https://techgrowup.net/react-component-basic/</link>
					<comments>https://techgrowup.net/react-component-basic/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[techgrowup]]></dc:creator>
		<pubDate>Sun, 27 Apr 2025 18:00:00 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Hooks]]></category>
		<category><![CDATA[Props]]></category>
		<category><![CDATA[State]]></category>
		<category><![CDATA[useEffect]]></category>
		<category><![CDATA[クラスコンポーネント]]></category>
		<category><![CDATA[コンポーネント]]></category>
		<category><![CDATA[関数コンポーネント]]></category>
		<guid isPermaLink="false">https://techgrowup.net/?p=2817</guid>

					<description><![CDATA[はじめに Reactを初めて学ぶ人が最初につまづきやすいのが「コンポーネント」の概念です。コンポーネントはUIを部品化し、再利用可能な塊として扱う手法。公式ドキュメント （https://react.dev/learn# [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">はじめに</h1>



<p class="wp-block-paragraph">Reactを初めて学ぶ人が最初につまづきやすいのが「コンポーネント」の概念です。コンポーネントはUIを部品化し、再利用可能な塊として扱う手法。公式ドキュメント （<a rel="noopener" target="_blank" class="" href="https://react.dev/learn#components%EF%BC%89">https://react.dev/learn#components）<span class="fa fa-external-link external-icon anchor-icon"></span></a> では「コンポーネントは関数と同じ」と説明していますが、実際にコードを書くときにはPropsやState、Hooksと組み合わせるため、学習のハードルが高く感じられることもあります。本記事ではReact 18+最新情報を交え、関数コンポーネント、クラスコンポーネント、Props、State、Hooks、コンポジションや最適化パターンまで丁寧に解説します。</p>



<h2 class="wp-block-heading">コンポーネントとは何か</h2>



<p class="wp-block-paragraph">コンポーネントは「UI部品」のようなもので、HTMLとJavaScriptを一体化して定義できます。例えば「ボタン」や「入力フォーム」のようなパーツを1つのファイルとして切り出し、 他の箇所から呼び出して使い回せるのが最大の利点です。</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="// Button.jsx
export function Button({ label, onClick }) {
  return &lt;button onClick={onClick}&gt;{label}&lt;/button&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: #6A9955">// Button.jsx</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">Button</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">label</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">onClick</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: #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: #9CDCFE">onClick</span><span style="color: #569CD6">}</span><span style="color: #808080">&gt;</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">label</span><span style="color: #569CD6">}</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">button</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">上記のように、<code>Button</code> コンポーネントを定義し、<code>label</code> や <code>onClick</code> をPropsで受け取ることで、使う場所ごとに見た目や挙動を変えられます。</p>



<h2 class="wp-block-heading">関数コンポーネントの基礎</h2>



<h3 class="wp-block-heading">宣言方法</h3>



<p class="wp-block-paragraph">関数コンポーネントはJavaScriptの関数として定義し、必ず1つのJSX要素を返します。</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 Greeting({ name }) {
  return &lt;h1&gt;こんにちは、{name}さん！&lt;/h1&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">Greeting</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">name</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: #808080">&lt;</span><span style="color: #569CD6">h1</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">こんにちは、</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">name</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4">さん！</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">h1</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">ESLintやTypeScript環境では <code>React.FC</code> 型を使って型注釈を付けるケースもあります。</p>



<h3 class="wp-block-heading">Propsの受け渡し</h3>



<p class="wp-block-paragraph">Propsはコンポーネントを呼び出す側で指定します。</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="&lt;Greeting name=&quot;太郎&quot; /&gt;
&lt;Greeting name=&quot;花子&quot; /&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: #808080">&lt;</span><span style="color: #4EC9B0">Greeting</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">name</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;太郎&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span></span>
<span class="line"><span style="color: #808080">&lt;</span><span style="color: #4EC9B0">Greeting</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">name</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;花子&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span></span></code></pre></div>



<p class="wp-block-paragraph">複数のPropsを使う場合はオブジェクト形式でまとめて受け取り、分割代入で取り出します。</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 Profile({ avatarUrl, username, bio }) { /* … */ }" 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">Profile</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">avatarUrl</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">username</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">bio</span><span style="color: #D4D4D4"> }) { </span><span style="color: #6A9955">/* … */</span><span style="color: #D4D4D4"> }</span></span></code></pre></div>



<h2 class="wp-block-heading">クラスコンポーネントとの違い</h2>



<p class="wp-block-paragraph">かつてReactはクラスコンポーネントが主流でした。2025年現在はHooksの登場で関数コンポーネントが主役ですが、既存コードやライフサイクルメソッドの学習に役立つため、基本を抑えておくと理解が深まります。</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 React from 'react';

class Greeting extends React.Component {
  render() {
    return &lt;h1&gt;こんにちは、{this.props.name}さん！&lt;/h1&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">React</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">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Greeting</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">extends</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">React</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">Component</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">render</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: #808080">&lt;</span><span style="color: #569CD6">h1</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">こんにちは、</span><span style="color: #569CD6">{this</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">props</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">name</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4">さん！</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">h1</span><span style="color: #808080">&gt;</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></code></pre></div>



<ul class="wp-block-list">
<li><strong>State管理</strong>：クラスでは <code>this.state</code> と <code>this.setState()</code></li>



<li><strong>ライフサイクル</strong>：<code>componentDidMount</code>, <code>componentDidUpdate</code>, <code>componentWillUnmount</code></li>
</ul>



<p class="wp-block-paragraph">Hooksを使えば同等の処理が関数コンポーネントで実現可能です。</p>



<h2 class="wp-block-heading">Stateの扱い方</h2>



<h3 class="wp-block-heading">useStateフック</h3>



<p class="wp-block-paragraph">Stateは「変化する値」を保持し、再レンダーを引き起こす仕組みです。関数コンポーネントでは <code>useState</code> を使って簡単にStateを定義できます。</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 { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  return (
    &lt;&gt;
      &lt;p&gt;現在のカウント: {count}&lt;/p&gt;
      &lt;button onClick={() =&gt; setCount(count + 1)}&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">useState</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">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">count</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">setCount</span><span style="color: #D4D4D4">] = </span><span style="color: #DCDCAA">useState</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">現在のカウント: </span><span style="color: #569CD6">{</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">setCount</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 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>
<span class="line"></span></code></pre></div>



<ul class="wp-block-list">
<li><strong>初期値</strong>：<code>useState(0)</code> の <code>0</code> 部分</li>



<li><strong>更新関数</strong>：<code>setCount</code> を呼ぶと再レンダーが発生</li>
</ul>



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



<ul class="wp-block-list">
<li><strong>不変性</strong>：Stateオブジェクトを直接変更せず、必ず更新関数を使う</li>



<li><strong>遅延初期化</strong>：複雑な計算が必要な場合は関数を渡して一度だけ実行</li>
</ul>



<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 [todos, setTodos] = useState(() =&gt; loadTodosFromLocalStorage());" 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">todos</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">setTodos</span><span style="color: #D4D4D4">] = </span><span style="color: #DCDCAA">useState</span><span style="color: #D4D4D4">(() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">loadTodosFromLocalStorage</span><span style="color: #D4D4D4">());</span></span></code></pre></div>



<h2 class="wp-block-heading">Props vs State</h2>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>Props</th><th>State</th></tr></thead><tbody><tr><td>定義場所</td><td>親コンポーネントが渡す</td><td>自身のコンポーネント内で定義</td></tr><tr><td>役割</td><td>親からの読み取り専用の値</td><td>パーツ内部で変化する値</td></tr><tr><td>更新</td><td>親が再レンダーされる必要あり</td><td>更新関数を呼ぶだけで自動的に再レンダー</td></tr></tbody></table></div></figure>



<p class="wp-block-paragraph">Propsを変更したい場合は「親コンポーネント」が再レンダーされて新しいPropsを渡す仕組みになります。</p>



<h2 class="wp-block-heading">コンポーネントの合成（Composition）</h2>



<p class="wp-block-paragraph">Reactでは<strong>コンポジション</strong>が主流で、親子や兄弟のようにコンポーネントを入れ子にして機能を組み立てます。</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 Card({ children }) {
  return &lt;div className=&quot;card&quot;&gt;{children}&lt;/div&gt;;
}

function App() {
  return (
    &lt;Card&gt;
      &lt;h2&gt;タイトル&lt;/h2&gt;
      &lt;p&gt;内容テキスト&lt;/p&gt;
    &lt;/Card&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">Card</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">children</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: #808080">&lt;</span><span style="color: #569CD6">div</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">className</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;card&quot;</span><span style="color: #808080">&gt;</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">children</span><span style="color: #569CD6">}</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">div</span><span style="color: #808080">&gt;</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">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">App</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;</span><span style="color: #4EC9B0">Card</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">h2</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">タイトル</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">h2</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">p</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">内容テキスト</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: #4EC9B0">Card</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>



<ul class="wp-block-list">
<li><strong>children</strong>：<code>&lt;Card>…&lt;/Card></code> の中身を受け取る特殊Props</li>



<li><strong>再利用性</strong>：見た目のフレームと中身を分離できるため、多用途に使える</li>
</ul>



<h2 class="wp-block-heading">ライフサイクルとuseEffect</h2>



<h3 class="wp-block-heading">useEffectの基本</h3>



<p class="wp-block-paragraph">副作用（データフェッチ、購読、手動DOM操作など）を扱う際に使うフック。</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 { useEffect, useState } from 'react';

function DataFetcher({ url }) {
  const [data, setData] = useState(null);
  useEffect(() =&gt; {
    fetch(url)
      .then(r =&gt; r.json())
      .then(json =&gt; setData(json));
  }, [url]); // urlが変わったときだけ再実行
  return data ? &lt;pre&gt;{JSON.stringify(data)}&lt;/pre&gt; : &lt;p&gt;読み込み中…&lt;/p&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">useEffect</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">useState</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">DataFetcher</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">url</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">data</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">setData</span><span style="color: #D4D4D4">] = </span><span style="color: #DCDCAA">useState</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">useEffect</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: #DCDCAA">fetch</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">url</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">      .</span><span style="color: #DCDCAA">then</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">r</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">r</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">json</span><span style="color: #D4D4D4">())</span></span>
<span class="line"><span style="color: #D4D4D4">      .</span><span style="color: #DCDCAA">then</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">json</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">setData</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">json</span><span style="color: #D4D4D4">));</span></span>
<span class="line"><span style="color: #D4D4D4">  }, [</span><span style="color: #9CDCFE">url</span><span style="color: #D4D4D4">]); </span><span style="color: #6A9955">// urlが変わったときだけ再実行</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">data</span><span style="color: #D4D4D4"> ? </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">pre</span><span style="color: #808080">&gt;</span><span style="color: #569CD6">{</span><span style="color: #4FC1FF">JSON</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">stringify</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">data</span><span style="color: #D4D4D4">)</span><span style="color: #569CD6">}</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">pre</span><span style="color: #808080">&gt;</span><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">読み込み中…</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">p</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<ul class="wp-block-list">
<li><strong>第2引数</strong>：依存配列。空配列 <code>[]</code> ならマウント時のみ実行</li>



<li><strong>クリーンアップ</strong>：関数を返すとアンマウント時に実行</li>
</ul>



<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="useEffect(() =&gt; {
  const id = setInterval(tick, 1000);
  return () =&gt; clearInterval(id);
}, []);" 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">useEffect</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: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">id</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">setInterval</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">tick</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1000</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: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">clearInterval</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">id</span><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>componentDidMount</code> → <code>useEffect(() => {...}, [])</code></li>



<li><code>componentDidUpdate</code> → <code>useEffect(() => {...}, [deps])</code></li>



<li><code>componentWillUnmount</code> → <code>useEffect(() => { return cleanup }, [])</code></li>
</ul>



<h2 class="wp-block-heading">パフォーマンス最適化</h2>



<h3 class="wp-block-heading">React.memo</h3>



<p class="wp-block-paragraph">関数コンポーネントをラップして、Propsが変わらない限り再レンダーを防ぐ。</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="const ExpensiveComponent = React.memo(function({ value }) {
  // 重い計算...
  return &lt;span&gt;{value}&lt;/span&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">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">ExpensiveComponent</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">React</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">memo</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">function</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: #6A9955">// 重い計算...</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">span</span><span style="color: #808080">&gt;</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">value</span><span style="color: #569CD6">}</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">span</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">});</span></span></code></pre></div>



<h3 class="wp-block-heading">useCallback / useMemo</h3>



<ul class="wp-block-list">
<li><strong>useCallback</strong>：コールバック関数をメモ化</li>
</ul>



<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 handleClick = useCallback(() =&gt; { /* ... */ }, [deps]);" 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">handleClick</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">useCallback</span><span style="color: #D4D4D4">(() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> { </span><span style="color: #6A9955">/* ... */</span><span style="color: #D4D4D4"> }, [</span><span style="color: #9CDCFE">deps</span><span style="color: #D4D4D4">]);</span></span></code></pre></div>



<ul class="wp-block-list">
<li><strong>useMemo</strong>：計算結果をメモ化</li>
</ul>



<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 result = useMemo(() =&gt; expensiveCalculation(a, b), [a, b]);" 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">result</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">useMemo</span><span style="color: #D4D4D4">(() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">expensiveCalculation</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">a</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">b</span><span style="color: #D4D4D4">), [</span><span style="color: #9CDCFE">a</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">b</span><span style="color: #D4D4D4">]);</span></span></code></pre></div>



<h3 class="wp-block-heading">Virtualized List</h3>



<p class="wp-block-paragraph">大量データをリスト表示する場合は <code>react-window</code> や <code>react-virtualized</code> を使って、可視領域のみDOM生成する。</p>



<h2 class="wp-block-heading">コンポーネント設計パターン</h2>



<h3 class="wp-block-heading">Container / Presentational</h3>



<ul class="wp-block-list">
<li><strong>Container</strong>：データ取得やState管理を担当</li>



<li><strong>Presentational</strong>：UI描画のみを担当</li>
</ul>



<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 UserContainer() {
  const [user, setUser] = useState(null);
  useEffect(() =&gt; fetchUser().then(setUser), []);
  return user ? &lt;UserProfile data={user} /&gt; : &lt;Loading /&gt;;
}
function UserProfile({ data }) { /* UIのみ */ }" 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">UserContainer</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">user</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">setUser</span><span style="color: #D4D4D4">] = </span><span style="color: #DCDCAA">useState</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">useEffect</span><span style="color: #D4D4D4">(() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">fetchUser</span><span style="color: #D4D4D4">().</span><span style="color: #DCDCAA">then</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">setUser</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">user</span><span style="color: #D4D4D4"> ? </span><span style="color: #808080">&lt;</span><span style="color: #4EC9B0">UserProfile</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">data</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">user</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span><span style="color: #D4D4D4"> : </span><span style="color: #808080">&lt;</span><span style="color: #4EC9B0">Loading</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"><span style="color: #569CD6">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">UserProfile</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">data</span><span style="color: #D4D4D4"> }) { </span><span style="color: #6A9955">/* UIのみ */</span><span style="color: #D4D4D4"> }</span></span></code></pre></div>



<h3 class="wp-block-heading">Compound Components</h3>



<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="function Tabs({ children }) {
  const [active, setActive] = useState(0);
  return /* contextでactiveとsetActiveを渡す */;
}
Tabs.List = function({ children }) { /* タブ見出し */ };
Tabs.Panel = function({ index, children }) { /* コンテンツ */ };" 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">Tabs</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">children</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">active</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">setActive</span><span style="color: #D4D4D4">] = </span><span style="color: #DCDCAA">useState</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 style="color: #6A9955">/* contextでactiveとsetActiveを渡す */</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"><span style="color: #9CDCFE">Tabs</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">List</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">function</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">children</span><span style="color: #D4D4D4"> }) { </span><span style="color: #6A9955">/* タブ見出し */</span><span style="color: #D4D4D4"> };</span></span>
<span class="line"><span style="color: #9CDCFE">Tabs</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">Panel</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">function</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">index</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">children</span><span style="color: #D4D4D4"> }) { </span><span style="color: #6A9955">/* コンテンツ */</span><span style="color: #D4D4D4"> };</span></span></code></pre></div>



<h2 class="wp-block-heading">テストと型安全</h2>



<h3 class="wp-block-heading">テスト例（React Testing Library）</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="import { render, fireEvent } from '@testing-library/react';
import Counter from './Counter';
test('クリックで増加', () =&gt; {
  const { getByText } = render(&lt;Counter /&gt;);
  const btn = getByText(/増やす/);
  fireEvent.click(btn);
  expect(getByText(/現在のカウント: 1/)).toBeInTheDocument();
});" 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">render</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">fireEvent</span><span style="color: #D4D4D4"> } </span><span style="color: #C586C0">from</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;@testing-library/react&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #C586C0">import</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">Counter</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">from</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;./Counter&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #DCDCAA">test</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;クリックで増加&#39;</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: #569CD6">const</span><span style="color: #D4D4D4"> { </span><span style="color: #4FC1FF">getByText</span><span style="color: #D4D4D4"> } = </span><span style="color: #DCDCAA">render</span><span style="color: #D4D4D4">(</span><span style="color: #808080">&lt;</span><span style="color: #4EC9B0">Counter</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</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">btn</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">getByText</span><span style="color: #D4D4D4">(</span><span style="color: #D16969">/増やす/</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">fireEvent</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">click</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">btn</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">expect</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">getByText</span><span style="color: #D4D4D4">(</span><span style="color: #D16969">/現在のカウント: 1/</span><span style="color: #D4D4D4">)).</span><span style="color: #DCDCAA">toBeInTheDocument</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">});</span></span></code></pre></div>



<h3 class="wp-block-heading">TypeScriptとの併用</h3>



<p class="wp-block-paragraph">コンポーネントに型注釈を付けると、Propsのうっかりミスをコンパイル時に検出できます。</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="interface ButtonProps { label: string; onClick: () =&gt; void; }
export function Button({ label, onClick }: ButtonProps) { /* ... */ }" 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">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ButtonProps</span><span style="color: #D4D4D4"> { </span><span style="color: #9CDCFE">label</span><span style="color: #D4D4D4">: </span><span style="color: #4EC9B0">string</span><span style="color: #D4D4D4">; </span><span style="color: #DCDCAA">onClick</span><span style="color: #D4D4D4">: () </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4">; }</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">Button</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">label</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">onClick</span><span style="color: #D4D4D4"> }: </span><span style="color: #4EC9B0">ButtonProps</span><span style="color: #D4D4D4">) { </span><span style="color: #6A9955">/* ... */</span><span style="color: #D4D4D4"> }</span></span></code></pre></div>



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



<p class="wp-block-paragraph">Reactコンポーネントは「UIを部品化して組み合わせる」ための基本単位です。関数コンポーネントとクラスコンポーネントの違い、PropsとState、Hooks、コンポジション、最適化パターンをしっかり理解すれば、堅牢で再利用性の高いUIを効率的に開発できます。公式ドキュメントを自分のプロジェクトに落とし込む際には、ここで解説した多彩なパターンをぜひ試してみてください。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://techgrowup.net/react-component-basic/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 14:18:56 by W3 Total Cache
-->