<?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>React  |  OZの教える×プログラミング成長記</title>
	<atom:link href="https://oz006.com/category/react/feed/" rel="self" type="application/rss+xml" />
	<link>https://oz006.com</link>
	<description></description>
	<lastBuildDate>Sat, 19 Apr 2025 12:43:47 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.2</generator>

<image>
	<url>https://oz006.com/wp-content/uploads/2024/10/cropped-OZLogo-32x32.png</url>
	<title>React  |  OZの教える×プログラミング成長記</title>
	<link>https://oz006.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>LaravelとReactで実装するSPAメッセージ機能：リロードなしでUXを向上させる方法</title>
		<link>https://oz006.com/spa-not-reload/</link>
					<comments>https://oz006.com/spa-not-reload/#respond</comments>
		
		<dc:creator><![CDATA[oz]]></dc:creator>
		<pubDate>Sat, 19 Apr 2025 12:43:46 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<guid isPermaLink="false">https://oz006.com/?p=611</guid>

					<description><![CDATA[Contents はじめに従来の実装とSPA実装の違い従来の実装（ページリロードあり）SPA実装（リロードなし）実装方法バックエンド（Laravel）の実装フロントエンド（React/TypeScript）の実装実装のメ [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="1000" height="1000" src="https://oz006.com/wp-content/uploads/2025/04/DALL·E-2025-04-19-21.42.02-A-futuristic-web-browser-interface-showing-a-high-tech-webpage-that-updates-content-in-real-time-without-reloading.-The-screen-is-filled-with-dynamic-.webp" alt="" class="wp-image-613" srcset="https://oz006.com/wp-content/uploads/2025/04/DALL·E-2025-04-19-21.42.02-A-futuristic-web-browser-interface-showing-a-high-tech-webpage-that-updates-content-in-real-time-without-reloading.-The-screen-is-filled-with-dynamic-.webp 1000w, https://oz006.com/wp-content/uploads/2025/04/DALL·E-2025-04-19-21.42.02-A-futuristic-web-browser-interface-showing-a-high-tech-webpage-that-updates-content-in-real-time-without-reloading.-The-screen-is-filled-with-dynamic--300x300.webp 300w, https://oz006.com/wp-content/uploads/2025/04/DALL·E-2025-04-19-21.42.02-A-futuristic-web-browser-interface-showing-a-high-tech-webpage-that-updates-content-in-real-time-without-reloading.-The-screen-is-filled-with-dynamic--150x150.webp 150w, https://oz006.com/wp-content/uploads/2025/04/DALL·E-2025-04-19-21.42.02-A-futuristic-web-browser-interface-showing-a-high-tech-webpage-that-updates-content-in-real-time-without-reloading.-The-screen-is-filled-with-dynamic--768x768.webp 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></figure>



<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame2 preset6 animation-fade rtoc_open default" data-id="611" data-theme="Cocoon Child">
			<div id="rtoc-mokuji-title" class=" rtoc_left">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">はじめに</a></li><li class="rtoc-item"><a href="#rtoc-2">従来の実装とSPA実装の違い</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-3">従来の実装（ページリロードあり）</a></li><li class="rtoc-item"><a href="#rtoc-4">SPA実装（リロードなし）</a></li></ul></li><li class="rtoc-item"><a href="#rtoc-5">実装方法</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-6">バックエンド（Laravel）の実装</a></li><li class="rtoc-item"><a href="#rtoc-7">フロントエンド（React/TypeScript）の実装</a></li></ul></li><li class="rtoc-item"><a href="#rtoc-8">実装のメリット</a></li><li class="rtoc-item"><a href="#rtoc-9">注意点とさらなる改善点</a></li><li class="rtoc-item"><a href="#rtoc-10">まとめ</a></li></ol></div><h2 id="rtoc-1"  class="wp-block-heading">はじめに</h2>



<p class="wp-block-paragraph">Webアプリケーションにおいて、ユーザー体験（UX）は非常に重要な要素です。特にチャットやメッセージ機能では、ページのリロードが発生するとユーザーの操作が中断され、スムーズな会話体験が損なわれてしまいます。今回は、Laravel（バックエンド）とReact（フロントエンド）を使用して、ページをリロードせずにメッセージを送信できるSPA（Single Page Application）形式の実装方法について解説します。</p>



<h2 id="rtoc-2"  class="wp-block-heading">従来の実装とSPA実装の違い</h2>



<h3 id="rtoc-3"  class="wp-block-heading">従来の実装（ページリロードあり）</h3>



<p class="wp-block-paragraph">従来の実装では、フォーム送信時に以下のような流れになります。</p>



<ol class="wp-block-list">
<li>ユーザーがメッセージを入力して送信ボタンをクリック</li>



<li>フォームがサーバーにPOSTリクエストを送信</li>



<li>サーバーがデータを処理し、新しいページをレンダリング</li>



<li>ブラウザが完全に画面をリロード</li>



<li>ユーザーは入力位置や画面の状態を失う</li>
</ol>



<h3 id="rtoc-4"  class="wp-block-heading">SPA実装（リロードなし）</h3>



<p class="wp-block-paragraph">SPA実装では、フォーム送信時に以下のような流れになります。</p>



<ol class="wp-block-list">
<li>ユーザーがメッセージを入力して送信ボタンをクリック</li>



<li>JavaScriptがAPIリクエストをサーバーに送信</li>



<li>サーバーがデータを処理し、JSONレスポンスを返す</li>



<li>フロントエンドがレスポンスを受け取り、UIを更新</li>



<li>ユーザーの操作が中断されない</li>
</ol>



<h2 id="rtoc-5"  class="wp-block-heading">実装方法</h2>



<p class="wp-block-paragraph">今回は、LaravelとReact（TypeScript）を使用したSPAメッセージ機能の実装方法を紹介します。</p>



<h3 id="rtoc-6"  class="wp-block-heading">バックエンド（Laravel）の実装</h3>



<p class="wp-block-paragraph">まず、メッセージ送信を処理するコントローラーを修正します。従来のリダイレクト処理に加えて、JSONレスポンスを返すようにします。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-php" data-lang="PHP"><code>public function store(Request $request, ConversationGroup $conversationGroup): JsonResponse|RedirectResponse
{
    // バリデーション
    $request-&gt;validate([
        &#39;message&#39; =&gt; &#39;required|string|max:1000&#39;,
    ]);

    // ユーザー権限チェック
    if (!$conversationGroup-&gt;hasParticipant(Auth::id())) {
        abort(403, &#39;Unauthorized action.&#39;);
    }

    // メッセージ作成
    $message = new DirectMessage([
        &#39;sender_id&#39; =&gt; Auth::id(),
        &#39;message&#39; =&gt; $request-&gt;message,
    ]);

    $conversationGroup-&gt;messages()-&gt;save($message);
    $conversationGroup-&gt;touch(); // updated_atを更新

    // Ajax リクエストの場合は JSON レスポンスを返す
    if ($request-&gt;expectsJson() || $request-&gt;ajax()) {
        return response()-&gt;json([
            &#39;success&#39; =&gt; true,
            &#39;message&#39; =&gt; $message-&gt;load(&#39;sender&#39;),
        ]);
    }

    // 通常のフォーム送信の場合はリダイレクト
    return redirect()-&gt;back();
}</code></pre></div>



<p class="wp-block-paragraph">このコントローラーのポイントは以下の通りです。</p>



<ul class="wp-block-list">
<li>JsonResponse|RedirectResponseで両方のレスポンスタイプをサポート</li>



<li>リクエストタイプに応じて適切なレスポンスを返す</li>



<li>APIリクエストの場合は送信者情報も含めて返す</li>
</ul>



<h3 id="rtoc-7"  class="wp-block-heading">フロントエンド（React/TypeScript）の実装</h3>



<p class="wp-block-paragraph">次に、React側でのメッセージ送信処理を実装します。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-ts" data-lang="TypeScript"><code>import { useState, useEffect, useRef } from &quot;react&quot;;
import { useForm } from &quot;@inertiajs/react&quot;;
import axios from &quot;axios&quot;;
import DirectMessage, { DirectMessageType } from &quot;@/Components/DirectMessage&quot;;

// コンポーネント内
export default function Show({
    auth,
    conversationGroup,
    messages: initialMessages,
    participants,
}) {
    // メッセージの状態管理
    const [messages, setMessages] = useState&lt;DirectMessageType[]&gt;(initialMessages);
    const [sending, setSending] = useState(false);
    const messagesContainerRef = useRef&lt;HTMLDivElement&gt;(null);

    const { data, setData, errors, reset } = useForm({
        message: &quot;&quot;,
    });

    // メッセージ送信処理
    const handleSubmit = async (e: React.FormEvent) =&gt; {
        e.preventDefault();
        
        if (!data.message.trim() || sending) {
            return;
        }
        
        setSending(true);
        
        try {
            // CSRFトークンの取得
            const csrfToken = document.querySelector(&#39;meta[name=&quot;csrf-token&quot;]&#39;)?.getAttribute(&#39;content&#39;) || &#39;&#39;;
            
            // APIでメッセージを送信
            const response = await axios.post(
                route(&quot;messages.store&quot;, conversationGroup.id), 
                data,
                {
                    headers: {
                        &#39;Content-Type&#39;: &#39;application/json&#39;,
                        &#39;X-CSRF-TOKEN&#39;: csrfToken
                    }
                }
            );
            
            // 成功したら新しいメッセージを追加
            if (response.data && response.data.message) {
                const newMessage: DirectMessageType = {
                    ...response.data.message,
                    sender: auth.user
                };
                
                setMessages([...messages, newMessage]);
                reset(&quot;message&quot;);
            }
        } catch (error) {
            console.error(&#39;メッセージ送信エラー:&#39;, error);
        } finally {
            setSending(false);
        }
    };

    // メッセージが追加されたらスクロール位置を最下部に移動
    useEffect(() =&gt; {
        if (messagesContainerRef.current) {
            messagesContainerRef.current.scrollTop =
                messagesContainerRef.current.scrollHeight;
        }
    }, [messages]);

    // JSXの返却（省略）
}</code></pre></div>



<p class="wp-block-paragraph">フロントエンド実装のポイントは以下の通りです。</p>



<ol class="wp-block-list">
<li>状態管理</li>
</ol>



<ul class="wp-block-list">
<li>useStateでメッセージリストと送信中の状態を管理</li>



<li>初期データはpropsから取得</li>
</ul>



<ol class="wp-block-list">
<li>非同期処理</li>
</ol>



<ul class="wp-block-list">
<li>async/awaitを使った非同期処理</li>



<li>送信中の状態管理（二重送信防止）</li>



<li>エラーハンドリング</li>
</ul>



<ol class="wp-block-list">
<li>UX向上</li>
</ol>



<ul class="wp-block-list">
<li>新しいメッセージ送信後に自動的に入力欄をリセット</li>



<li>新しいメッセージ追加時に自動スクロール</li>



<li>送信中の視覚的フィードバック</li>
</ul>



<h2 id="rtoc-8"  class="wp-block-heading">実装のメリット</h2>



<p class="wp-block-paragraph">このSPA実装には以下のようなメリットがあります。</p>



<ol class="wp-block-list">
<li>シームレスなユーザー体験</li>
</ol>



<ul class="wp-block-list">
<li>ページがリロードされないため、会話のコンテキストが維持される</li>



<li>スムーズな操作感でユーザーのフラストレーションが軽減</li>
</ul>



<ol class="wp-block-list">
<li>レスポンシブな操作感</li>
</ol>



<ul class="wp-block-list">
<li>送信後すぐにUIが更新されるため、操作への即時フィードバックがある</li>



<li>読み込み中やエラー状態も視覚的に表現できる</li>
</ul>



<ol class="wp-block-list">
<li>サーバー負荷の軽減</li>
</ol>



<ul class="wp-block-list">
<li>必要なデータのみを送受信するため、帯域幅の使用が最適化される</li>



<li>全ページを再読み込みする必要がないため、サーバーリソースの使用が効率化</li>
</ul>



<ol class="wp-block-list">
<li>拡張性</li>
</ol>



<ul class="wp-block-list">
<li>この基本的なパターンを応用して、リアルタイム通知やタイピングインジケーターなどの機能を追加可能</li>
</ul>



<h2 id="rtoc-9"  class="wp-block-heading">注意点とさらなる改善点</h2>



<ol class="wp-block-list">
<li>エラーハンドリング</li>
</ol>



<ul class="wp-block-list">
<li>ネットワークエラーや認証エラーなど、様々なエラーケースに対応する必要がある</li>



<li>ユーザーにわかりやすいエラーメッセージを表示する</li>
</ul>



<ol class="wp-block-list">
<li>バリデーション</li>
</ol>



<ul class="wp-block-list">
<li>フロントエンドでも入力値のバリデーションを行うことでUXを向上させられる</li>
</ul>



<ol class="wp-block-list">
<li>リアルタイム通信</li>
</ol>



<ul class="wp-block-list">
<li>WebSocketやPusherなどを活用して、真のリアルタイムチャットにアップグレードできる</li>
</ul>



<ol class="wp-block-list">
<li>オフライン対応</li>
</ol>



<ul class="wp-block-list">
<li>Service Workerを使用してオフライン時のメッセージ送信をキューに入れるなどの機能も可能</li>
</ul>



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



<p class="wp-block-paragraph">今回は、LaravelとReactを使ったSPA形式のメッセージ送信機能の実装方法を紹介しました。ページをリロードせずにメッセージを送信することで、ユーザー体験が大幅に向上します。この実装パターンは、チャット機能だけでなく、コメント機能やフォーム送信など、様々な場面で応用可能です。ユーザー体験を重視したウェブアプリケーション開発の参考にしていただければ幸いです。最後に、SPAのアプローチはモダンなWeb開発における標準的な手法になりつつあります。ユーザーの期待も高まる中、このような実装を取り入れることは、現代のWebアプリケーション開発において非常に重要なスキルとなっています。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://oz006.com/spa-not-reload/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Reactでユーザーフレンドリーなモバイルメニューを実装する方法</title>
		<link>https://oz006.com/react-useref-mobile-menu/</link>
					<comments>https://oz006.com/react-useref-mobile-menu/#respond</comments>
		
		<dc:creator><![CDATA[oz]]></dc:creator>
		<pubDate>Sun, 13 Apr 2025 18:56:13 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<guid isPermaLink="false">https://oz006.com/?p=609</guid>

					<description><![CDATA[今回はReactを使って、ハンバーガーメニューをクリックした時だけでなく、メニュー外の部分をクリックした時にも自動的に閉じる機能を実装しました。この記事では、特にuseRefフックの使い方にフォーカスして解説します。 C [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img decoding="async" width="1000" height="1000" src="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp" alt="" class="wp-image-385" srcset="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp 1000w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-300x300.webp 300w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-150x150.webp 150w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-768x768.webp 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></figure>



<p class="wp-block-paragraph">今回はReactを使って、<strong><span class="marker-under">ハンバーガーメニューをクリックした時だけでなく、メニュー外の部分をクリックした時にも自動的に閉じる機能を実装</span></strong>しました。この記事では、特に<strong>useRefフックの使い方</strong>にフォーカスして解説します。</p>



<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame2 preset6 animation-fade rtoc_open default" data-id="609" data-theme="Cocoon Child">
			<div id="rtoc-mokuji-title" class=" rtoc_left">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">実装の目的</a></li><li class="rtoc-item"><a href="#rtoc-2">主要な技術要素</a></li><li class="rtoc-item"><a href="#rtoc-3">コードの仕組み</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-4">1.&nbsp;必要な状態と参照の設定</a></li><li class="rtoc-item"><a href="#rtoc-5">2. メニューの開閉アニメーションの制御</a></li><li class="rtoc-item"><a href="#rtoc-6">3. メニュー外クリックの検出</a></li><li class="rtoc-item"><a href="#rtoc-7">4. DOM要素への参照の設定</a></li></ul></li><li class="rtoc-item"><a href="#rtoc-8">useRefとは「名札」のようなもの</a></li><li class="rtoc-item"><a href="#rtoc-9">useRefを具体例で理解する</a></li><li class="rtoc-item"><a href="#rtoc-10">なぜ「保持」と言うのか？</a></li><li class="rtoc-item"><a href="#rtoc-11">具体的な使い道</a></li><li class="rtoc-item"><a href="#rtoc-12">今回のコードでの具体的な流れ</a></li><li class="rtoc-item"><a href="#rtoc-13">まとめるとこんなイメージ</a></li><li class="rtoc-item"><a href="#rtoc-14">まとめ</a></li></ol></div><h2 id="rtoc-1"  class="wp-block-heading">実装の目的</h2>



<p class="wp-block-paragraph">モバイルサイトでよく見かけるハンバーガーメニュー。一般的には、メニューボタンをクリックすると開き、もう一度ボタンをクリックすると閉じる仕組みになっています。しかし、ユーザー体験を向上させるためには、「メニュー以外の場所をクリックしても閉じる」機能があると便利です。</p>



<h2 id="rtoc-2"  class="wp-block-heading">主要な技術要素</h2>



<p class="wp-block-paragraph">実装には以下のReactフックを使用しています。</p>



<ul class="wp-block-list">
<li>useState: メニューの開閉状態を管理</li>



<li>useRef: DOM要素を参照するために使用</li>



<li>useEffect: クリックイベントの設定と解除</li>
</ul>



<h2 id="rtoc-3"  class="wp-block-heading">コードの仕組み</h2>



<h3 id="rtoc-4"  class="wp-block-heading">1.&nbsp;必要な状態と参照の設定</h3>



<p class="wp-block-paragraph">まず、メニューの状態を管理するための変数と、DOM要素を参照するためのuseRefを設定します。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-ts" data-lang="TypeScript"><code>// メニューの状態を管理
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [menuVisible, setMenuVisible] = useState(false);
const [animating, setAnimating] = useState(false);

// DOM要素への参照
const mobileMenuRef = useRef&lt;HTMLDivElement&gt;(null);
const mobileButtonRef = useRef&lt;HTMLButtonElement&gt;(null);</code></pre></div>



<p class="wp-block-paragraph">ここでは3つの状態変数を使っています。</p>



<ul class="wp-block-list">
<li>mobileMenuOpen: メニューが開いているかどうかの論理値</li>



<li>menuVisible: メニューがDOM上に存在するかどうかの論理値（アニメーション用）</li>



<li>animating: アニメーション中かどうかの論理値</li>
</ul>



<p class="wp-block-paragraph">また、useRefを使って2つのDOM要素への参照を作成しています。</p>



<ul class="wp-block-list">
<li>mobileMenuRef: メニュー本体への参照</li>



<li>mobileButtonRef: ハンバーガーボタンへの参照</li>
</ul>



<h3 id="rtoc-5"  class="wp-block-heading">2. メニューの開閉アニメーションの制御</h3>



<p class="wp-block-paragraph">メニューの開閉状態が変わった時のアニメーション処理：</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-ts" data-lang="TypeScript"><code>useEffect(() =&gt; {
    if (mobileMenuOpen) {
        // メニューを開く処理
        setMenuVisible(true);
        setAnimating(true);
        setTimeout(() =&gt; setAnimating(false), 300);
    } else if (menuVisible) {
        // メニューを閉じる処理
        setAnimating(true);
        setTimeout(() =&gt; {
            setMenuVisible(false);
            setAnimating(false);
        }, 300);
    }
}, [mobileMenuOpen]);</code></pre></div>



<p class="wp-block-paragraph">このuseEffectはmobileMenuOpenの値が変わるたびに実行されます：</p>



<ul class="wp-block-list">
<li>メニューを開く時：まずmenuVisibleをtrueにしてDOM上に表示し、アニメーション開始</li>



<li>メニューを閉じる時：アニメーションを開始し、300ms後にDOM上から削除</li>
</ul>



<h3 id="rtoc-6"  class="wp-block-heading">3. メニュー外クリックの検出</h3>



<p class="wp-block-paragraph">ここが今回の実装の核となる部分です。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-ts" data-lang="TypeScript"><code>useEffect(() =&gt; {
    const handleClickOutside = (event: MouseEvent) =&gt; {
        // ボタン自体のクリックは無視（トグル動作は別のハンドラで処理）
        if (
            mobileMenuRef.current && 
            !mobileMenuRef.current.contains(event.target as Node) &&
            mobileButtonRef.current &&
            !mobileButtonRef.current.contains(event.target as Node) &&
            menuVisible &&
            !animating
        ) {
            setMobileMenuOpen(false);
        }
    };

    document.addEventListener(&quot;mousedown&quot;, handleClickOutside);
    return () =&gt; {
        document.removeEventListener(&quot;mousedown&quot;, handleClickOutside);
    };
}, [menuVisible, animating]);</code></pre></div>



<p class="wp-block-paragraph">この処理の流れを詳しく見ていきましょう。</p>



<ol class="wp-block-list">
<li>document全体に対してmousedownイベントリスナーを設定</li>



<li>クリックが発生したときにhandleClickOutside関数が呼ばれる</li>



<li>この関数内で複数の条件を確認：</li>
</ol>



<ul class="wp-block-list">
<li>mobileMenuRef.currentが存在する（メニューがレンダリングされている）</li>



<li>クリックされた要素がメニュー内部ではない</li>



<li>mobileButtonRef.currentが存在する（ボタンがレンダリングされている）</li>



<li>クリックされた要素がボタン自体ではない</li>



<li>メニューが表示中である</li>



<li>アニメーション中ではない</li>
</ul>



<ol class="wp-block-list">
<li>すべての条件を満たせば、メニューを閉じる指示を出す</li>
</ol>



<p class="wp-block-paragraph">特に重要なのは、useRefを使ってDOM要素を参照し、containsメソッドでクリックされた要素がメニュー内部かボタン自体かを判定している点です。</p>



<h3 id="rtoc-7"  class="wp-block-heading">4. DOM要素への参照の設定</h3>



<p class="wp-block-paragraph">最後に、作成したuseRef参照をJSX内の実際のDOM要素に紐付けます。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-ts" data-lang="TypeScript"><code>&lt;button
    className=&quot;l-header__mobile-button&quot;
    onClick={toggleMobileMenu}
    aria-label=&quot;メニューを開く&quot;
    ref={mobileButtonRef}  // ここでボタン要素を参照
&gt;
    {/* ボタンの中身 */}
&lt;/button&gt;

{menuVisible && (
    &lt;div
        className={`l-header__mobile-menu ${
            mobileMenuOpen ? &quot;menu-fade-in&quot; : &quot;menu-fade-out&quot;
        }`}
        ref={mobileMenuRef}  // ここでメニュー要素を参照
    &gt;
        {/* メニューの中身 */}
    &lt;/div&gt;
)}</code></pre></div>



<p class="wp-block-paragraph">ref属性にuseRefで作成した参照を指定することで、React側からそのDOM要素にアクセスできるようになります。</p>



<h2 id="rtoc-8"  class="wp-block-heading">useRefとは「名札」のようなもの</h2>



<p class="wp-block-paragraph"><strong><span class="marker-under">useRefは、Reactで特定のHTML要素（DOMノード）に「名札」をつけるような機能</span></strong>です。この<strong><span class="marker-under">「名札」があれば、後からその要素を見つけたり、操作したりすることができます</span></strong>。</p>



<h2 id="rtoc-9"  class="wp-block-heading">useRefを具体例で理解する</h2>



<p class="wp-block-paragraph">例えば、教室に30人の生徒がいるとします。先生が「窓側の3番目に座っている人」と言うより、「田中さん」と名前で呼んだ方が簡単ですよね。useRefはまさにそのような「名前」の役割を果たします。</p>



<p class="wp-block-paragraph">コードで表すと、、、</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-ts" data-lang="TypeScript"><code>// 「田中さん」という名札を用意する
const 田中さんRef = useRef(null);

// 実際の生徒（HTML要素）に名札をつける
&lt;div ref={田中さんRef}&gt;田中&lt;/div&gt;

// これで後から「田中さん」を見つけることができる
console.log(田中さんRef.current); // この生徒（div要素）を取得</code></pre></div>



<h4 class="wp-block-heading">実際のメニュー実装での使い方</h4>



<p class="wp-block-paragraph">今回のモバイルメニューの例では、</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-ts" data-lang="TypeScript"><code>// メニューとボタンの名札を用意
const mobileMenuRef = useRef(null);
const mobileButtonRef = useRef(null);

// 実際の要素に名札をつける
&lt;button ref={mobileButtonRef}&gt;メニュー&lt;/button&gt;
&lt;div ref={mobileMenuRef}&gt;メニューの内容&lt;/div&gt;</code></pre></div>



<p class="wp-block-paragraph">ここで重要なのは、mobileMenuRef.currentと書くと、実際のHTML要素（このケースでは&lt;div&gt;）そのものにアクセスできるという点です。</p>



<h2 id="rtoc-10"  class="wp-block-heading">なぜ「保持」と言うのか？</h2>



<p class="wp-block-paragraph">Reactでは通常、コンポーネントが再レンダリングされると変数がリセットされますが、useRefで作った参照（名札）はリセットされません。つまり：</p>



<ol class="wp-block-list">
<li>最初のレンダリングで「名札」を特定の要素につける</li>



<li>コンポーネントが再レンダリングされても</li>



<li>その「名札」は同じ要素を指し続ける</li>
</ol>



<p class="wp-block-paragraph">これが「参照を保持する」という意味です。</p>



<h2 id="rtoc-11"  class="wp-block-heading">具体的な使い道</h2>



<p class="wp-block-paragraph">特にDOM操作が必要な場合に便利です：</p>



<ol class="wp-block-list">
<li>要素の測定：要素の高さや幅を取得する</li>



<li>フォーカス制御：特定の入力欄に自動でフォーカスを当てる</li>



<li>クリック判定：今回のように「この要素の内側がクリックされたかどうか」を判断する</li>
</ol>



<h2 id="rtoc-12"  class="wp-block-heading">今回のコードでの具体的な流れ</h2>



<p class="wp-block-paragraph">①mobileMenuRefとmobileButtonRefという2つの「名札」を用意</p>



<p class="wp-block-paragraph">②それぞれをメニュー本体とメニューボタンの要素に付ける</p>



<p class="wp-block-paragraph">③画面上のどこかがクリックされた時：</p>



<ol class="wp-block-list"></ol>



<ul class="wp-block-list">
<li>mobileMenuRef.current.contains(event.target)で「クリックされた場所はメニュー内？」を判定</li>



<li>mobileButtonRef.current.contains(event.target)で「クリックされた場所はボタン？」を判定</li>
</ul>



<p class="wp-block-paragraph">④どちらでもない場合はメニュー外のクリックと判断してメニューを閉じる</p>



<ol class="wp-block-list"></ol>



<h2 id="rtoc-13"  class="wp-block-heading">まとめるとこんなイメージ</h2>



<p class="wp-block-paragraph">useRefは「これが〇〇だよ」と名前をつける仕組み<br>↓<br>その名前を使って、後からその要素を見つけられる<br>↓<br>特にReactで普通に書けない複雑なDOM操作ができるようになる</p>



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



<p class="wp-block-paragraph">今回の実装では、useRefを使ってDOM要素を参照することで、「メニュー外をクリックすると閉じる」という直感的な操作を実現しました。これによりユーザー体験が向上し、より使いやすいモバイルメニューが実装できました。特に以下の点がポイントです：</p>



<ol class="wp-block-list">
<li>useRefでDOM要素への参照を保持</li>



<li>containsメソッドでクリック位置を判定</li>



<li>複数の条件を組み合わせて適切なタイミングでメニューを閉じる</li>



<li>アニメーション中の誤操作を防止</li>
</ol>



<p class="wp-block-paragraph">この実装パターンは、ドロップダウンメニューやモーダルウィンドウなど、他のUI要素にも応用できる汎用的なテクニックです。React開発では、このような小さな工夫の積み重ねが、全体的なユーザー体験の向上につながります。ぜひ皆さんのプロジェクトにも取り入れてみてください！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://oz006.com/react-useref-mobile-menu/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>React入門第１２回~useContextとuseReducerとは？~</title>
		<link>https://oz006.com/react-usecontext-usereducer/</link>
					<comments>https://oz006.com/react-usecontext-usereducer/#respond</comments>
		
		<dc:creator><![CDATA[oz]]></dc:creator>
		<pubDate>Wed, 20 Nov 2024 06:10:27 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<guid isPermaLink="false">https://oz006.com/?p=476</guid>

					<description><![CDATA[Contents 複雑な状態管理に向けて 1. useContextって何？ グローバルな状態を共有する 2. 状態が複雑な場合に便利なuseReducer 3. useContextとuseReducerを組み合わせる [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img decoding="async" width="1000" height="1000" src="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp" alt="" class="wp-image-385" srcset="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp 1000w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-300x300.webp 300w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-150x150.webp 150w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-768x768.webp 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></figure>



<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame2 preset6 animation-fade rtoc_open default" data-id="476" data-theme="Cocoon Child">
			<div id="rtoc-mokuji-title" class=" rtoc_left">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">複雑な状態管理に向けて</a></li><li class="rtoc-item"><a href="#rtoc-2">1. <code>useContext</code>って何？</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-3">グローバルな状態を共有する</a></li></ul></li><li class="rtoc-item"><a href="#rtoc-4">2. 状態が複雑な場合に便利な<code>useReducer</code></a></li><li class="rtoc-item"><a href="#rtoc-5">3. <code>useContext</code>と<code>useReducer</code>を組み合わせる</a></li><li class="rtoc-item"><a href="#rtoc-6">次回に向けて</a></li></ol></div><h2 id="rtoc-1"  class="wp-block-heading">複雑な状態管理に向けて</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="OZ" class="speech-icon-image"/></figure><div class="speech-name">OZ</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">先生！前回のStateの記事で、<code>useState</code>を使って状態を管理する方法は分かりました。でも、<strong><span class="marker-under">大きなアプリだともっと複雑な状態管理が必要になる</span></strong>って聞きました！！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="プロ太" class="speech-icon-image"/></figure><div class="speech-name">プロ太</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">いい質問だね、OZくん！そのとおり。<code>useState</code>は便利だけど、状態が多くなるとコードが煩雑になることがあります！そこで登場するのが、<strong><span class="marker-under">【<code>useContext】</code>と【<code>useReducer】</code></span><span class="marker-under">です</span><span class="marker-under">。</span></strong></p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><code>useContext</code>と<code>useReducer</code>？それってどんなものなんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">簡単に言うと、<code>useContext</code>は<strong>データをコンポーネント間で簡単に共有</strong>するための仕組みで、<code>useReducer</code>は<strong>複雑な状態管理</strong>をシンプルにするためのものなんだ。それじゃあ、順番に説明していこう！</p>
</div></div>



<h2 id="rtoc-2"  class="wp-block-heading">1. <code>useContext</code>って何？</h2>



<h3 id="rtoc-3"  class="wp-block-heading">グローバルな状態を共有する</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><code>useContext</code>を使うと、<strong><span class="marker-under">親から子へpropsで直接データを渡す方法ではなく、コンポーネントのどこからでもデータを受け取れるようになる</span></strong>んです。まず、例を見てみましょう！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>import { createContext, useContext } from &quot;react&quot;;

const UserContext = createContext();

const ParentComponent = () =&gt; {
  const user = { name: &quot;OZ&quot;, age: 18 };

  return (
    &lt;UserContext.Provider value={user}&gt;
      &lt;ChildComponent /&gt;
    &lt;/UserContext.Provider&gt;
  );
};

const ChildComponent = () =&gt; {
  const user = useContext(UserContext);
  return (
    &lt;p&gt;
      こんにちは！{user.name}くん！年齢は、{user.age}ですね！
    &lt;/p&gt;
  );
};

export default ParentComponent;</code></pre></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="399" height="52" src="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-18-12.24.09.png" alt="" class="wp-image-477" srcset="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-18-12.24.09.png 399w, https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-18-12.24.09-300x39.png 300w" sizes="auto, (max-width: 399px) 100vw, 399px" /></figure>



<h5 class="wp-block-heading">コード解説</h5>



<ol class="wp-block-list">
<li><strong><code>createContext</code></strong>
<ul class="wp-block-list">
<li>グローバルにデータを管理するための「箱」を作成。ここでは<code>UserContext</code>を作っています。</li>
</ul>
</li>



<li><strong><code>UserContext.Provider</code></strong>
<ul class="wp-block-list">
<li>データ（<code>value</code>プロパティ）を子コンポーネントに共有するための仕組み。</li>
</ul>
</li>



<li><strong><code>useContext(UserContext)</code></strong>
<ul class="wp-block-list">
<li>子コンポーネントがデータを受け取るときに使う。</li>
</ul>
</li>
</ol>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">これなら、親から子に毎回<code>props</code>を渡さなくてもいいんですね！</p>
</div></div>



<h2 id="rtoc-4"  class="wp-block-heading">2. 状態が複雑な場合に便利な<code>useReducer</code></h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><code>useReducer</code>は、複雑な状態を管理するときに便利なフックです。<strong><span class="marker-under"><code>useState</code>と似てるけど、状態の更新ロジックを<code>reducer</code>という関数にまとめて書けるのが特徴</span></strong>です。</p>
</div></div>



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



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>import { useReducer } from &quot;react&quot;;

const initialState = { count: 0 };

const reducer = (state, action) =&gt; {
  switch (action.type) {
    case &quot;increment&quot;:
      return { count: state.count + 1 };
    case &quot;decrement&quot;:
      return { count: state.count - 1 };
    case &quot;reset&quot;:
      return initialState;
    default:
      throw new Error(&quot;不明なアクションです&quot;);
  }
};

const Counter = () =&gt; {
  const [state, dispatch] = useReducer(reducer, initialState);
  debugger;
  return (
    &lt;div&gt;
      &lt;p&gt;カウント：{state.count}&lt;/p&gt;
      &lt;button onClick={() =&gt; dispatch({ type: &quot;increment&quot; })}&gt;増やす&lt;/button&gt;
      &lt;button onClick={() =&gt; dispatch({ type: &quot;decrement&quot; })}&gt;減らす&lt;/button&gt;
      &lt;button onClick={() =&gt; dispatch({ type: &quot;reset&quot; })}&gt;リセット&lt;/button&gt;
    &lt;/div&gt;
  );
};

export default Counter;</code></pre></div>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="画面収録 2024 11 18 12 50 27" width="1256" height="707" src="https://www.youtube.com/embed/wUd56S0MRLk?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h4 class="wp-block-heading">カウンターアプリのコード解説</h4>



<h5 class="wp-block-heading">全体の流れ</h5>



<ul class="wp-block-list">
<li>このアプリはカウンターを操作するもので、ボタンを押すと数値が増減したり、リセットされたりします。</li>



<li>状態管理に<code>useReducer</code>を使い、状態（<code>state</code>）を更新するための「アクション」（<code>dispatch</code>）を呼び出します。</li>
</ul>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const initialState = { count: 0 };</code></pre></div>



<p class="wp-block-paragraph">これは状態の初期値です<br><code>count: 0</code>として、最初はカウンターが0に設定されます</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>function reducer(state, action) {
  switch (action.type) {
    case &#39;increment&#39;:
      return { count: state.count + 1 };
    case &#39;decrement&#39;:
      return { count: state.count - 1 };
    case &#39;reset&#39;:
      return initialState;
    default:
      throw new Error(&#39;Unhandled action type: &#39; + action.type);
  }
}</code></pre></div>



<ul class="wp-block-list">
<li><strong>引数の説明</strong>
<ul class="wp-block-list">
<li><code>state</code>：現在の状態（例：<code>{ count: 0 }</code>）</li>



<li><code>action</code>：どのように状態を更新するかを指定するオブジェクト（例：<code>{ type: 'increment' }</code>）</li>
</ul>
</li>



<li><strong>switch文の動き</strong>
<ol class="wp-block-list">
<li><code>action.type</code>が<code>increment</code>の場合、<code>count</code>を1増やした新しい状態を返します</li>



<li><code>decrement</code>の場合、<code>count</code>を1減らします</li>



<li><code>reset</code>の場合、<code>initialState</code>に戻します</li>



<li>想定外の<code>action.type</code>が渡された場合はエラーを投げます（バグ防止）</li>
</ol>
</li>
</ul>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const [state, dispatch] = useReducer(reducer, initialState);</code></pre></div>



<p class="wp-block-paragraph"><code>useReducer</code>は2つの引数を受け取ります。</p>



<ol class="wp-block-list">
<li>状態を更新するための<code>reducer</code>関数</li>



<li>状態の初期値（<code>initialState</code>）</li>
</ol>



<p class="wp-block-paragraph">戻り値として、次の2つが返されます。</p>



<ol class="wp-block-list">
<li><code>state</code>：現在の状態（例：<code>{ count: 0 }</code>）</li>



<li><code>dispatch</code>：状態を更新するための関数<br>（例：<code>dispatch({ type: 'increment' })</code>）</li>
</ol>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>return (
  &lt;div&gt;
    &lt;p&gt;カウント: {state.count}&lt;/p&gt;
    &lt;button onClick={() =&gt; dispatch({ type: &#39;increment&#39; })}&gt;増やす&lt;/button&gt;
    &lt;button onClick={() =&gt; dispatch({ type: &#39;decrement&#39; })}&gt;減らす&lt;/button&gt;
    &lt;button onClick={() =&gt; dispatch({ type: &#39;reset&#39; })}&gt;リセット&lt;/button&gt;
  &lt;/div&gt;
);</code></pre></div>



<p class="wp-block-paragraph"><strong><code>state.count</code></strong>：現在のカウント値を表示。<strong>各ボタン</strong>：<code>onClick</code>イベントで<code>dispatch</code>を呼び出し、状態を更新します。</p>



<ul class="wp-block-list">
<li><code>increment</code>ボタン：カウントを1増やす</li>



<li><code>decrement</code>ボタン：カウントを1減らす</li>



<li><code>reset</code>ボタン：初期状態にリセットする</li>
</ul>



<h2 id="rtoc-5"  class="wp-block-heading">3. <code>useContext</code>と<code>useReducer</code>を組み合わせる</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><code>useContext</code>と<code>useReducer</code>を組み合わせると、もっと便利になりますよ。例えば、大規模アプリで複数のコンポーネント間で状態を共有しながら管理する場合を考えてみましょう！！</p>
</div></div>



<h4 class="wp-block-heading">Todoリストの例</h4>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>import React, { createContext, useReducer, useContext } from &#39;react&#39;;

// 初期状態とreducer関数
const initialState = [];
function reducer(state, action) {
  switch (action.type) {
    case &#39;add&#39;:
      return [...state, action.payload];
    case &#39;remove&#39;:
      return state.filter((_, index) =&gt; index !== action.payload);
    default:
      throw new Error(&#39;Unhandled action type: &#39; + action.type);
  }
}

// Contextの作成
const TodoContext = createContext();

function TodoProvider({ children }) {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    &lt;TodoContext.Provider value={{ state, dispatch }}&gt;
      {children}
    &lt;/TodoContext.Provider&gt;
  );
}

function TodoList() {
  const { state, dispatch } = useContext(TodoContext);

  return (
    &lt;div&gt;
      &lt;ul&gt;
        {state.map((todo, index) =&gt; (
          &lt;li key={index}&gt;
            {todo} &lt;button onClick={() =&gt; dispatch({ type: &#39;remove&#39;, payload: index })}&gt;削除&lt;/button&gt;
          &lt;/li&gt;
        ))}
      &lt;/ul&gt;
      &lt;button
        onClick={() =&gt; dispatch({ type: &#39;add&#39;, payload: `新しいタスク ${state.length + 1}` })}
      &gt;
        タスクを追加
      &lt;/button&gt;
    &lt;/div&gt;
  );
}

function App() {
  return (
    &lt;TodoProvider&gt;
      &lt;TodoList /&gt;
    &lt;/TodoProvider&gt;
  );
}

export default App;
</code></pre></div>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="画面収録 2024 11 19 9 04 41" width="1256" height="707" src="https://www.youtube.com/embed/61geUwN-ZvY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h5 class="wp-block-heading">Todoリストのコード解説</h5>



<h6 class="wp-block-heading">全体の流れ</h6>



<ul class="wp-block-list">
<li>このアプリはタスク（Todo）を管理するもので、新しいタスクを追加したり、削除したりできます。</li>



<li>複数のコンポーネントで状態を共有するため、<code>useReducer</code>と<code>useContext</code>を組み合わせています。</li>
</ul>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const initialState = [];</code></pre></div>



<p class="wp-block-paragraph">タスクが最初は何もない状態を配列<code>[]</code>で定義しています。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>function reducer(state, action) {
  switch (action.type) {
    case &#39;add&#39;:
      return [...state, action.payload];
    case &#39;remove&#39;:
      return state.filter((_, index) =&gt; index !== action.payload);
    default:
      throw new Error(&#39;Unhandled action type: &#39; + action.type);
  }
}</code></pre></div>



<p class="wp-block-paragraph"><strong>動作の説明</strong></p>



<ol class="wp-block-list">
<li><code>add</code>アクションの場合：
<ul class="wp-block-list">
<li><code>action.payload</code>（新しいタスク）を現在の状態（配列）に追加します。</li>



<li><code>[...state, action.payload]</code>はスプレッド構文を使って新しい配列を作成します。</li>
</ul>
</li>



<li><code>remove</code>アクションの場合：
<ul class="wp-block-list">
<li>指定されたインデックス（<code>action.payload</code>）を除く配列を返します。</li>



<li><code>filter</code>メソッドで不要なタスクを除外します。</li>
</ul>
</li>
</ol>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const TodoContext = createContext();</code></pre></div>



<p class="wp-block-paragraph"><code>TodoContext</code>を作成し、アプリ全体で状態を共有できる仕組みを用意します。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>function TodoProvider({ children }) {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    &lt;TodoContext.Provider value={{ state, dispatch }}&gt;
      {children}
    &lt;/TodoContext.Provider&gt;
  );
}</code></pre></div>



<p class="wp-block-paragraph"><code>useReducer</code>で管理している状態と<code>dispatch</code>をコンテキストに渡します。<br>子コンポーネントで<code>TodoContext</code>を使えば、これらの値を利用できます。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>function TodoList() {
  const { state, dispatch } = useContext(TodoContext);

  return (
    &lt;div&gt;
      &lt;ul&gt;
        {state.map((todo, index) =&gt; (
          &lt;li key={index}&gt;
            {todo} &lt;button onClick={() =&gt; dispatch({ type: &#39;remove&#39;, payload: index })}&gt;削除&lt;/button&gt;
          &lt;/li&gt;
        ))}
      &lt;/ul&gt;
      &lt;button
        onClick={() =&gt; dispatch({ type: &#39;add&#39;, payload: `新しいタスク ${state.length + 1}` })}
      &gt;
        タスクを追加
      &lt;/button&gt;
    &lt;/div&gt;
  );
}</code></pre></div>



<p class="wp-block-paragraph"><strong><code>useContext</code>の利用</strong></p>



<ul class="wp-block-list">
<li><code>TodoContext</code>から<code>state</code>と<code>dispatch</code>を取得します。</li>
</ul>



<p class="wp-block-paragraph"><strong>タスクの表示</strong></p>



<ul class="wp-block-list">
<li><code>state.map</code>で現在のタスクをループし、それぞれをリストアイテム（<code>&lt;li&gt;</code>）として表示します。</li>



<li>各アイテムには削除ボタンがあり、クリックすると<code>remove</code>アクションが呼び出されます。</li>
</ul>



<p class="wp-block-paragraph"><strong>タスクの追加</strong></p>



<ul class="wp-block-list">
<li>追加ボタンを押すと、<code>dispatch</code>で<code>add</code>アクションを呼び出し、新しいタスクを配列に追加します。</li>
</ul>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！こうすれば、どのコンポーネントからでもTodoリストを操作できますね！</p>
</div></div>



<h2 id="rtoc-6"  class="wp-block-heading">次回に向けて</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">先生、今日もたくさん学べました！次はReduxの話を教えてください！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">もちろん！<strong>Reduxは、さらに状態管理を強力にしてくれるライブラリ</strong>です。次回を楽しみにしていてくださいね！</p>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://oz006.com/react-usecontext-usereducer/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>React入門第１１回 ~CSS-in-JSでスタイリングしよう~</title>
		<link>https://oz006.com/react-css-in-js/</link>
					<comments>https://oz006.com/react-css-in-js/#respond</comments>
		
		<dc:creator><![CDATA[oz]]></dc:creator>
		<pubDate>Tue, 19 Nov 2024 00:08:29 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<guid isPermaLink="false">https://oz006.com/?p=468</guid>

					<description><![CDATA[Contents CSS-in-JSとは？ styled-componentsの基本 CSS-in-JSを使うメリット メリットの活用例 CSS-in-JSの注意点とデメリット スタイルの「継承」も可能！ CSS-in- [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="1000" src="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp" alt="" class="wp-image-385" srcset="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp 1000w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-300x300.webp 300w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-150x150.webp 150w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-768x768.webp 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame2 preset6 animation-fade rtoc_open default" data-id="468" data-theme="Cocoon Child">
			<div id="rtoc-mokuji-title" class=" rtoc_left">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">CSS-in-JSとは？</a></li><li class="rtoc-item"><a href="#rtoc-2">styled-componentsの基本</a></li><li class="rtoc-item"><a href="#rtoc-3">CSS-in-JSを使うメリット</a></li><li class="rtoc-item"><a href="#rtoc-4">メリットの活用例</a></li><li class="rtoc-item"><a href="#rtoc-5">CSS-in-JSの注意点とデメリット</a></li><li class="rtoc-item"><a href="#rtoc-6">スタイルの「継承」も可能！</a></li><li class="rtoc-item"><a href="#rtoc-7">CSS-in-JSのまとめ</a></li></ol></div><h2 id="rtoc-1"  class="wp-block-heading">CSS-in-JSとは？</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">プロ太先生！<span class="marker-under">CSS-in-JS</span>って、名前は聞いたことあるけど、普通のCSSとどう違うの？なんかJavaScriptの中にCSSを書くって聞いたけど…</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">CSS-in-JSはJavaScriptの中に直接CSSを書く方法です。これを使うと、各コンポーネントのスタイルをその場で書けるから、コードがまとまりやすくなりますね。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">へえ、じゃあ外部のCSSファイルがいらないってこと？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そういうことです！今回は<span class="marker-under">「styled-components」というライブラリ</span>を使って、CSS-in-JSの基礎を学んでみよう。では、まずサンプルコードを見ながら進めていきましょう！</p>
</div></div>



<h2 id="rtoc-2"  class="wp-block-heading">styled-componentsの基本</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">まず、CSS-in-JSの例として「styled-components」を使ってボタンを作ってみます。次のコードを見てください。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>import { useState } from &quot;react&quot;;
import styled from &quot;styled-components&quot;;

const StyledButton = styled.button`
  border-radius: 12px;
  border: none;
  display: block;
  width: 120px;
  height: 50px;
  margin: 20px auto;
  font-weight: bold;
  cursor: pointer;
  background-color: ${({ isActive }) =&gt; (isActive ? &quot;green&quot; : &quot;red&quot;)};
  color: white;
  transition: background-color 0.3s;

  &:hover {
    opacity: 0.8;
  }
`;

const StyledExample = () =&gt; {
  const [isActive, setIsActive] = useState(false);
  const handleClick = () =&gt; {
    setIsActive(!isActive);
  };
  return (
    &lt;StyledButton isActive={isActive} onClick={handleClick}&gt;
      クリックして色を変更
    &lt;/StyledButton&gt;
  );
};

export default StyledExample;</code></pre></div>



<p class="wp-block-paragraph">上記のコードを書けば、クリックすれば色が変わるボタンが作成できます。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="382" height="190" src="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-15-22.17.43.png" alt="" class="wp-image-469" srcset="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-15-22.17.43.png 382w, https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-15-22.17.43-300x149.png 300w" sizes="auto, (max-width: 382px) 100vw, 382px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="348" height="178" src="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-15-22.17.55.png" alt="" class="wp-image-470" srcset="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-15-22.17.55.png 348w, https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-15-22.17.55-300x153.png 300w" sizes="auto, (max-width: 348px) 100vw, 348px" /></figure>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">この「StyledButton」って何ですか？普通の<code>&lt;button></code>タグと何が違うんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">この<code>StyledButton</code>は、<strong><span class="marker-under">styled-componentsが提供する<code>styled.button</code>を使ってCSSを当てたボタン要素</span></strong>です。テンプレートリテラル内にCSSを書けるから、HTMLとCSSがまとまって見やすくなります。</p>
</div></div>



<h2 id="rtoc-3"  class="wp-block-heading">CSS-in-JSを使うメリット</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">じゃあ、CSS-in-JSを使うと何が便利なんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">いくつかメリットがあるから、順に見てみましょう。</p>
</div></div>



<ol class="wp-block-list">
<li><strong>スタイルがコンポーネントに密接する</strong><br>通常のCSSだと、コンポーネントとスタイルが別の場所にあるから探しにくいことがあるよね？でもCSS-in-JSなら、そのコンポーネントに関連するスタイルがすぐ近くにあるから、見通しがよくなるんだ。<br></li>



<li><strong>ユニークなクラス名が自動生成される</strong><br>例えば<code>StyledButton</code>のようなコンポーネントを作ると、styled-componentsはそのボタンのためだけのユニークなクラス名を自動で生成してくれる。だから、他のコンポーネントとスタイルがかぶる心配がないんだよ。<br></li>



<li><strong>スタイルの動的変更が簡単</strong><br>スタイルに<code>props</code>を渡すことで、見た目を動的に変えられるのも魅力だね。さっきの例でいうと、<code>isActive</code>が<code>true</code>になると背景色が緑になり、<code>false</code>の時は赤色になるように設定してある。</li>
</ol>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！スタイルをその場で変更できるんだね！<br>ゲームのキャラクターの衣装をボタン一つで変えるみたいに感じるな！</p>
</div></div>



<h2 id="rtoc-4"  class="wp-block-heading">メリットの活用例</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">「テーマ」を切り替えるような場合でも便利ですよ。次のコードでテーマの色を変える例を見てみよう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>import { useState } from &quot;react&quot;;
import styled from &quot;styled-components&quot;;

const ThemeButton = styled.button`
  background-color: ${(props) =&gt; (props.theme === &quot;dark&quot; ? &quot;black&quot; : &quot;white&quot;)};
  color: ${(props) =&gt; (props.theme === &quot;dark&quot; ? &quot;white&quot; : &quot;black&quot;)};
`;

const Example = () =&gt; {
  const [theme, setTheme] = useState(&quot;dark&quot;);
  const toggleTheme = () =&gt; {
    setTheme(theme === &quot;dark&quot; ? &quot;light&quot; : &quot;dark&quot;);
  };
  return (
    &lt;ThemeButton theme={theme} onClick={() =&gt; toggleTheme()}&gt;
      ボタン
    &lt;/ThemeButton&gt;
  );
};
export default Example;</code></pre></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="178" height="104" src="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-15-22.45.14.png" alt="" class="wp-image-471"/></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="182" height="108" src="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-15-22.45.23.png" alt="" class="wp-image-472"/></figure>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">おお！！ボタンを押すと色が変わるんですね！<br>こういうスタイルの切り替えが簡単にできるん便利ですね！！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そう、JavaScriptのif文や三項演算子を使って、条件によってスタイルを変えられるのもCSS-in-JSの強みですね！</p>
</div></div>



<h2 id="rtoc-5"  class="wp-block-heading">CSS-in-JSの注意点とデメリット</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">いいことばかりだけど、デメリットとか注意することはないんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">もちろん、ほんの少しデメリットもありますよ。ただ、それほど大きなものではありません。</p>
</div></div>



<ol class="wp-block-list">
<li><strong>パフォーマンス</strong><br>自動で生成されるスタイルはその分JavaScriptの処理が増えるから、大量のコンポーネントに対しては負荷がかかることもある。でも、一般的なプロジェクトではそれほど気にしなくても大丈夫です。<br></li>



<li><strong>可読性の低下</strong><br>クラス名が自動生成されるから、ブラウザのデバッグツールでスタイルを確認する時に、クラス名が「sc-bdnylx」といったランダムな文字列になっていて分かりにくいことがあります。</li>
</ol>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">確かに、クラス名がランダムだとスタイルを確認しづらいかもね。</p>
</div></div>



<h2 id="rtoc-6"  class="wp-block-heading">スタイルの「継承」も可能！</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">さらに実際のプロジェクトで使う場合、スタイルの「継承」も重要です。<strong><span class="marker-under"><code>styled()</code>を使って元のコンポーネントのスタイルを引き継ぐことができる</span></strong>んです。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const PrimaryButton = styled.button`
  background-color: blue;
  color: white;
  padding: 10px;
`;

const SecondaryButton = styled(PrimaryButton)`
  background-color: gray;
`;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><code>PrimaryButton</code>のスタイルを元に<code>SecondaryButton</code>を作ってるんですね！！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そう、こうすればスタイルの再利用が簡単にできるし、保守性も高くなりますよ。</p>
</div></div>



<h2 id="rtoc-7"  class="wp-block-heading">CSS-in-JSのまとめ</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">最後に、CSS-in-JSのメリットとデメリットをまとめておきますね。</p>
</div></div>



<p class="wp-block-paragraph"><strong>メリット</strong></p>



<ol class="wp-block-list">
<li>コンポーネントごとにスタイルを管理できるので、CSS設計が楽になる！</li>



<li>動的なスタイル変更が簡単。</li>



<li>ユニークなクラス名が自動生成され、スタイルが衝突しにくい。</li>
</ol>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">みなさんも、CSS-in-jSを使って独自のスタイルのあるアプリケーションをどんどん作ってみてくださいね！</p>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://oz006.com/react-css-in-js/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>React入門第１０回~filterメソッドを使ってみよう~</title>
		<link>https://oz006.com/react-filter-method/</link>
					<comments>https://oz006.com/react-filter-method/#respond</comments>
		
		<dc:creator><![CDATA[oz]]></dc:creator>
		<pubDate>Mon, 18 Nov 2024 02:48:57 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<guid isPermaLink="false">https://oz006.com/?p=447</guid>

					<description><![CDATA[filterメソッドを使ってみよう コード例1：動物リストをフィルターする コード解説 personオブジェクトにさらにaddressやjobといった新しいプロパティが追加された場合、それぞれを追加で書き込む必要が出てき [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="1000" src="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp" alt="" class="wp-image-385" srcset="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp 1000w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-300x300.webp 300w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-150x150.webp 150w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-768x768.webp 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<h2 id="rtoc-1"  class="wp-block-heading">filterメソッドを使ってみよう</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">プロ太先生、<strong><span class="marker-under"><code>filter</code>って何ですか？配列の中身を絞り込むって聞いたことがある</span></strong>んですが…。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><strong><span class="marker-under"><code>filter</code>は配列の中から条件に合った要素だけを取り出すためのメソッド</span></strong>ですね。たとえば、リストの中で特定の文字が含まれているものだけを表示したいときに使えるんです。こんなコードを書いてみましょう。フィルターで動物の名前を絞り込む例です。</p>
</div></div>



<p class="wp-block-paragraph">コード例1：動物リストをフィルターする</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>import { useState } from &quot;react&quot;;

const animals = [&quot;Tiger&quot;, &quot;Lion&quot;, &quot;Elephant&quot;];
// POINT filterメソッドの使い方
const Example = () =&gt; {
  const [filterVal, setFilterVal] = useState(&quot;&quot;);

  return (
    &lt;&gt;
      &lt;h3&gt;配列のフィルター&lt;/h3&gt;
      &lt;input
        type=&quot;text&quot;
        value={filterVal}
        onChange={(e) =&gt; setFilterVal(e.target.value)}
        placeholder=&quot;動物の名前を入力してみてね&quot;
      /&gt;
      &lt;ul&gt;
        {animals
          .filter((animal) =&gt; animal.includes(filterVal))
          .map((animal) =&gt; (
            &lt;li key={animal}&gt;{animal}&lt;/li&gt;
          ))}
      &lt;/ul&gt;
    &lt;/&gt;
  );
};

export default Example;
</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">まずは、<code>useState</code>を使って<code>filterVal</code>という値を管理しています。この<code>filterVal</code>には、OZくんがテキストボックスに入力した値が常にセットされるんです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど、テキストボックスで入力した内容がそのまま<code>filterVal</code>に入るんですね。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうです。そして、<code>animals.filter()</code>を使って、各要素に対して<code>filterVal</code>が含まれているかどうかを確認しています。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">{animals<br>.filter((animal) =&gt; animal.includes(filterVal))<br>の部分では、animalsの配列に対して、<code>includes</code>メソッドを使って、<code>filterVal</code>がその配列の要素に含まれているかチェックしているんですね。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">その通りです！そして、フィルターされた結果が<code>map</code>メソッドでリストとして表示されるわけだね。じゃあ、ちょっと実行して、テキストボックスに『Ti』とか入力してみてくれる？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">はい、やってみます！…おお、<code>Tiger</code>だけが出てきました！</p>
</div></div>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="フィルターメソッド練習" width="1256" height="942" src="https://www.youtube.com/embed/z3YcbtYz2ck?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">次に、もう少し複雑なデータのフィルターを試してみましょう。今回は人のプロフィールをフィルターします。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-file="Sample.jsx" data-lang="JavaScript"><code>import Profile from &quot;./components/Profile&quot;;
import { useState } from &quot;react&quot;;

const persons = [
  {
    name: &quot;Alex&quot;,
    age: 20,
    hobbies: [&quot;swimming&quot;, &quot;reading&quot;],
  },
  {
    name: &quot;Bella&quot;,
    age: 25,
    hobbies: [&quot;cooking&quot;, &quot;painting&quot;],
  },
  {
    name: &quot;Chris&quot;,
    age: 18,
    hobbies: [&quot;gaming&quot;, &quot;music&quot;, &quot;hiking&quot;],
  },
];

const Example = () =&gt; {
  const [filterVal, setFilterVal] = useState(&quot;&quot;);

  return (
    &lt;&gt;
      &lt;input
        type=&quot;text&quot;
        value={filterVal}
        onChange={(e) =&gt; setFilterVal(e.target.value)}
        placeholder=&quot;名前を入力してみてね&quot;
      /&gt;
      &lt;ul&gt;
        {persons
          .filter((person) =&gt; person.name.includes(filterVal))
          .map((person) =&gt; (
            &lt;li key={person.name}&gt;
              &lt;Profile {...person} /&gt;
            &lt;/li&gt;
          ))}
      &lt;/ul&gt;
    &lt;/&gt;
  );
};

export default Sample;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">この<code>Profile</code>コンポーネントは何をしているんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">この<code>Profile</code>コンポーネントが人物のプロフィールを表示してくれるんです。詳細をコードで確認してみましょう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-file="Profile.jsx" data-lang="JavaScript"><code>const Profile = ({ name, age, hobbies }) =&gt; {
  return (
    &lt;div&gt;
      &lt;hr /&gt;
      &lt;div&gt;名前: {name}&lt;/div&gt;
      &lt;div&gt;年齢: {age}&lt;/div&gt;
      &lt;div&gt;
        &lt;div&gt;趣味:&lt;/div&gt;
        &lt;ul&gt;
          {hobbies.map((hobby) =&gt; (
            &lt;li key={hobby}&gt;{hobby}&lt;/li&gt;
          ))}
        &lt;/ul&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
};

export default Profile;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">それじゃあ、まず、Sample.jsxファイルの、人物リスト<code>persons</code>のフィルター部分を詳しく解説していきますね。以下の部分です。filterメソッドについては解説済みですが、復習しておきましょう！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-file="Sample.jsx" data-lang="JavaScript"><code> &lt;ul&gt;
        {persons
          .filter((person) =&gt; person.name.includes(filterVal))
          .map((person) =&gt; (
            &lt;li key={person.name}&gt;
              &lt;Profile {...person} /&gt;
            &lt;/li&gt;
          ))}
      &lt;/ul&gt;</code></pre></div>



<h4 class="wp-block-heading"><strong>コード解説</strong></h4>



<ol class="wp-block-list">
<li><strong><code>persons.filter()</code>の部分</strong>：
<ul class="wp-block-list">
<li><strong><code>filter</code>メソッド</strong>は配列<code>persons</code>の各要素（ここでは<code>person</code>）を順にチェックして、特定の条件に合う要素だけを新しい配列にまとめます。</li>



<li><strong>条件</strong>としては、<code>person.name.includes(filterVal)</code>が<code>true</code>のときだけその<code>person</code>をフィルター結果に含めます。</li>



<li><strong><code>includes</code>メソッド</strong>は、文字列の中に指定した文字が含まれているかを確認します。この場合、<code>filterVal</code>の文字が<code>person.name</code>に含まれているかどうかをチェックしています。</li>
</ul>
</li>



<li><strong><code>map</code>メソッドでリストを表示</strong>：
<ul class="wp-block-list">
<li>フィルターで条件に合った人物の配列を得た後、その配列の各要素を<code>&lt;li&gt;</code>タグでリスト表示します。</li>



<li><code>person</code>のデータを<code>Profile</code>コンポーネントに渡して表示するために、<code>&lt;Profile {...person} /&gt;</code>と書かれています。これはスプレッド構文を使って、<code>person</code>オブジェクトの中身を<code>Profile</code>コンポーネントに渡しています。<br>この<code>{...person}</code>は、<code>person</code>オブジェクトの中にあるすべてのプロパティ（例えば、<code>name</code>、<code>age</code>、<code>hobbies</code>）を展開して、それぞれを<code>Profile</code>に一括で渡すという意味です。これで、<code>Profile</code>コンポーネントの中では、<code>name</code>、<code>age</code>、<code>hobbies</code>が個別のプロパティとして扱えるようになります。スプレッド構文を使わずに一つずつ渡すとしたら、以下のような感じになります。</li>
</ul>
</li>
</ol>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>&lt;Profile name={person.name} age={person.age} hobbies={person.hobbies} /&gt;</code></pre></div>



<p class="wp-block-paragraph"><code>person</code>オブジェクトにさらに<code>address</code>や<code>job</code>といった新しいプロパティが追加された場合、それぞれを追加で書き込む必要が出てきますが、スプレッド構文を使えば、オブジェクトの中身をまとめて展開できるから便利です。</p>



<p class="wp-block-paragraph">3.<strong><code>key</code>属性の追加</strong>：</p>



<ul id="block-7cf9382c-2f10-4759-a39d-8e9678ee3097" class="wp-block-list">
<li>Reactでは、リスト表示を行うときに<code>key</code>属性を指定することが推奨されています。ここでは、<code>key={person.name}</code>として、各人物の<code>name</code>を<code>key</code>に使っています。</li>



<li><code>key</code>はReactが各要素を識別するためのものなので、重複しない値（ユニークな値）である必要があります。</li>
</ul>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！<code>filter</code>と<code>map</code>が連携して、入力した名前に応じた人物だけがリストに表示されるんですね。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">その通り！そして、<code>Profile</code>コンポーネントに人物のデータを渡して、個別に表示するようにしているんです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">次に気になるのが<code>hobbies</code>の部分です。趣味のリストがどうやって表示されるのか教えてください！以下の部分です。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-file="Sample.jsx" data-lang="JavaScript"><code>&lt;ul&gt;
  {hobbies.map((hobby) =&gt; (
    &lt;li key={hobby}&gt;{hobby}&lt;/li&gt;
  ))}
&lt;/ul&gt;</code></pre></div>



<h4 class="wp-block-heading"><strong>コード解説</strong></h4>



<ol class="wp-block-list">
<li><strong><code>map</code>メソッド</strong>：
<ul class="wp-block-list">
<li><strong><code>map</code>メソッド</strong>は配列の各要素を順に処理し、処理結果を新しい配列として返します。この場合、<code>hobbies</code>配列の各<code>hobby</code>をリスト形式で表示しています。</li>



<li><code>hobbies.map((hobby) =&gt; ( ... ))</code>では、<code>hobby</code>が<code>hobbies</code>配列の各要素を順番に受け取って処理します。</li>
</ul>
</li>



<li><strong><code>&lt;li key={hobby}&gt;{hobby}&lt;/li&gt;</code>タグ</strong>：
<ul class="wp-block-list">
<li><code>&lt;li&gt;</code>タグの中に各<code>hobby</code>の内容が表示されます。これにより、趣味がリスト形式で一つずつ表示されるようになります。</li>



<li><strong><code>key</code>属性</strong>には<code>hobby</code>自体を指定しています。<code>hobby</code>がユニークであることが前提ですが、同じ趣味が含まれる場合には異なるキーを用意するか、他の値を使うことを検討する必要があります。</li>
</ul>
</li>
</ol>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><code>map</code>を使うことで配列の各要素を一つずつ表示できるんですね！これで趣味がリストとして表示されるわけですね。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">その通り！そして、<code>Profile</code>コンポーネントの中では、<code>hobbies</code>という配列を受け取って、趣味を一覧表示しているんだ。このようにコンポーネントの中で<code>map</code>を使えば、配列データを簡単にリスト表示できるようになりますよ！</p>
</div></div>



<h2 id="rtoc-2"  class="wp-block-heading">補足：filterメソッド第２引数・第３引数のReactでの使い方</h2>



<p class="wp-block-paragraph">filter メソッドの第2引数に渡すのは、<strong>各要素に対して呼び出されるコールバック関数</strong> です。このコールバック関数は、以下の3つの引数を取ることができます。</p>



<ul class="wp-block-list">
<li><strong>element:</strong> 現在の配列要素</li>



<li><strong>index:</strong> 現在の要素のインデックス</li>



<li><strong>array:</strong> 配列全体</li>
</ul>



<p class="wp-block-paragraph">つまり、<strong><span class="marker-under">上記３つのどれかでしぼっていくことができる</span></strong>ということです！！</p>



<h5 class="wp-block-heading">コールバック関数の役割</h5>



<p class="wp-block-paragraph">コールバック関数は、各要素に対して実行され、その戻り値が <code>true</code> の場合に、その要素が新しい配列に含まれます。つまり、<strong>条件を満たす要素だけを抽出する</strong> 働きをします。</p>



<p class="wp-block-paragraph"><strong>第１引数の活用例</strong></p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const numbers = [1, 2, 3, 4, 5];

// 偶数のみを抽出
const evenNumbers = numbers.filter(function(element) {
  return element % 2 === 0;
});

console.log(evenNumbers); // [2, 4]</code></pre></div>



<p class="wp-block-paragraph">この例では、<code>filter</code> メソッドのコールバック関数で、要素が偶数かどうかを判定しています。偶数の場合に <code>true</code> を返し、新しい配列 <code>evenNumbers</code> に追加されます。</p>



<p class="wp-block-paragraph"><strong>第２引数の活用例</strong></p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const words = [&#39;apple&#39;, &#39;banana&#39;, &#39;cherry&#39;, &#39;date&#39;];

// インデックスが偶数の要素のみを抽出
const evenIndexWords = words.filter((_, index) =&gt; {
  return index % 2 === 0;
});

console.log(evenIndexWords); // [&#39;apple&#39;, &#39;cherry&#39;]</code></pre></div>



<p class="wp-block-paragraph">この例では、<code>_</code> で要素の値は無視し、<code>index</code> を使ってインデックスが偶数の要素だけを抽出しています。</p>



<p class="wp-block-paragraph"><strong>第3引数 (array) の活用例</strong></p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const numbers = [1, 2, 3, 2, 1];

// 重複する要素を除去
const uniqueNumbers = numbers.filter((element, index, array) =&gt; {
  return array.indexOf(element) === index;
});

console.log(uniqueNumbers); // [1, 2, 3]</code></pre></div>



<p class="wp-block-paragraph">この例では、<code>array.indexOf(element)</code> で、要素が初めて現れるインデックスを取得し、それが現在のインデックスと一致する場合にのみ、その要素を新しい配列に追加しています。これにより、重複する要素を除去することができます。</p>



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



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">今日の授業内容で、配列のフィルターと表示のやり方が分かりました！実際にコードを書きながらやってみます！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">それが一番ですね！Reactの基本操作は慣れると応用が効くから、どんどん試してみましょう！</p>
</div></div>



<p class="wp-block-paragraph">このように、リストのフィルターと配列の表示を学ぶことで、データを動的に管理し表示する方法を理解できたかと思います。さらに実践で応用しながら身に着けていきましょう！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://oz006.com/react-filter-method/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>React入門第９回~配列を表示してみよう~</title>
		<link>https://oz006.com/react-map-key/</link>
					<comments>https://oz006.com/react-map-key/#respond</comments>
		
		<dc:creator><![CDATA[oz]]></dc:creator>
		<pubDate>Fri, 15 Nov 2024 03:53:06 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<guid isPermaLink="false">https://oz006.com/?p=442</guid>

					<description><![CDATA[Contents Reactで配列を表示するには？ map関数について filter関数について keyが必要な理由 keyをつける時の注意点 map関数補足：配列を返すのに、どうして表示される？ まとめ Reactで配 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="1000" src="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp" alt="" class="wp-image-385" srcset="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp 1000w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-300x300.webp 300w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-150x150.webp 150w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-768x768.webp 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame2 preset6 animation-fade rtoc_open default" data-id="442" data-theme="Cocoon Child">
			<div id="rtoc-mokuji-title" class=" rtoc_left">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">Reactで配列を表示するには？</a></li><li class="rtoc-item"><a href="#rtoc-2">map関数について</a></li><li class="rtoc-item"><a href="#rtoc-3">filter関数について</a></li><li class="rtoc-item"><a href="#rtoc-4">keyが必要な理由</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-5">keyをつける時の注意点</a></li></ul></li><li class="rtoc-item"><a href="#rtoc-6">map関数補足：配列を返すのに、どうして表示される？</a></li><li class="rtoc-item"><a href="#rtoc-7">まとめ</a></li></ol></div><h2 id="rtoc-1"  class="wp-block-heading">Reactで配列を表示するには？</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="OZ" class="speech-icon-image"/></figure><div class="speech-name">OZ</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">先生、ReactでWebサイトを作っているんですが、<strong><span class="marker-under">配列のデータを表示したいんです</span></strong>。どうすればいいですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="プロ太" class="speech-icon-image"/></figure><div class="speech-name">プロ太</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">具体例で説明していきましょう。例えば、好きなスポーツのリストを表示するプログラムを作ってみましょう！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const sports = [&quot;サッカー&quot;, &quot;野球&quot;, &quot;バスケ&quot;];

const SportsList = () =&gt; {
  return (
    &lt;&gt;
      &lt;h3&gt;人気のスポーツ&lt;/h3&gt;
      &lt;ul&gt;
        &lt;li&gt;{sports[0]}&lt;/li&gt;
        &lt;li&gt;{sports[1]}&lt;/li&gt;
        &lt;li&gt;{sports[2]}&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/&gt;
  );
};

export default SportsList;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！配列の要素を一つずつ指定して表示しているんですね。<strong><span class="marker-under-blue">でも、配列の要素が増えたら大変そう</span></strong>です…</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">その通りです！そこで、<strong>あまり使われない</strong>ですが、for文を使って書く方法を見てみましょう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const sports = [&quot;サッカー&quot;, &quot;野球&quot;, &quot;バスケ&quot;];

const SportsList = () =&gt; {
  const sportList = [];
  for (const sport of sports) {
    sportList.push(&lt;li&gt;{sport}&lt;/li&gt;);
  }
  
  return (
    &lt;&gt;
      &lt;h3&gt;人気のスポーツ&lt;/h3&gt;
      &lt;ul&gt;
        {sportList}
      &lt;/ul&gt;
    &lt;/&gt;
  );
};</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">おぉ！！なるほど！！<strong>for文を使うと、配列の要素が増えても対応できる</strong>んですね！でも、なぜこの書き方はあまり使われないんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">重要なポイントですね！実は、JSXには大事なルールがあります。<strong><span class="marker-under-blue">JSXの中の<code>{}</code>では、文（statement）を書くことができない</span></strong>んです。このあたりは前の授業で扱っているので、忘れていたら復習しておきましょう！</p>
</div></div>



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

<a href="https://oz006.com/react-jsx/" title="React入門第４回~JSX内でJSのコードを入れてみよう！~" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="160" height="90" src="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-160x90.webp" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-160x90.webp 160w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-120x68.webp 120w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-320x180.webp 320w" sizes="auto, (max-width: 160px) 100vw, 160px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">React入門第４回~JSX内でJSのコードを入れてみよう！~</div><div class="blogcard-snippet internal-blogcard-snippet">この記事では、JSX内でJSのコードを使用する方法を、高校生のOZくんと先生の対話形式で解説。変数や配列の表示方法、コメントの書き方、そしてJSXで使える『式』と使えない『文』の違いまで、実践的なコード例とともに分かりやすく学べます。React初心者にぴったりの入門ガイドです。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://oz006.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">oz006.com</div></div><div class="blogcard-date internal-blogcard-date"><div class="blogcard-post-date internal-blogcard-post-date">2024.11.07</div></div></div></div></a>
</div></figure>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なので、for文より<strong><span class="marker-under"><code>map</code>関数を使う方法がよく使われます</span></strong>。こんな感じです。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const sports = [&quot;サッカー&quot;, &quot;野球&quot;, &quot;バスケ&quot;];

const SportsList = () =&gt; {
  return (
    &lt;&gt;
      &lt;h3&gt;人気のスポーツ&lt;/h3&gt;
      &lt;ul&gt;
        {sports.map((sport) =&gt; (
          &lt;li&gt;{sport}&lt;/li&gt;
        ))}
      &lt;/ul&gt;
    &lt;/&gt;
  );
};</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">map関数を使うと、コードがすっきりしましたね！でも、map関数ってなんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><span class="marker-under"><strong>map関数は、配列の各要素に対して同じ処理を行い、新しい配列を作る関数</strong></span>です。この場合：</p>



<ol class="wp-block-list">
<li><code>sports</code>配列の各要素（sport）に対して</li>



<li><code>&lt;li&gt;{sport}&lt;/li&gt;</code>というJSXを作成</li>



<li>それらを新しい配列にまとめて返す</li>
</ol>



<p class="wp-block-paragraph">という処理を行っています。シンプルで読みやすいコードになりますよね！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-12 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ02.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！でも、map関数の使い方がまだよくわかりません..</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">では、map関数の使い方の特徴を先に説明しますね。</p>
</div></div>



<h2 id="rtoc-2"  class="wp-block-heading">map関数について</h2>



<p class="wp-block-paragraph"><code>map</code> 関数は、配列の各要素に対して指定した処理を行い、その結果を新しい配列として返すJavaScriptのメソッドです。元の配列は変更せず、新しい配列が生成されるため、安全にデータを操作できる便利な方法です。</p>



<p class="wp-block-paragraph"><strong>基本的な構文</strong></p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const newArray = array.map((element, index, array) =&gt; {
  // 要素ごとに行いたい処理
  return element * 2; // 例: 各要素を2倍にする
});</code></pre></div>



<p class="wp-block-paragraph"><code>map</code> 関数には、以下の3つの引数を取れるコールバック関数を渡せます。</p>



<ol class="wp-block-list">
<li><strong>element</strong>: 現在処理している配列の要素</li>



<li><strong>index</strong>（省略可能）: 現在の要素のインデックス</li>



<li><strong>array</strong>（省略可能）: <code>map</code> メソッドが実行される元の配列</li>
</ol>



<p class="wp-block-paragraph"><strong>簡単な例</strong></p>



<p class="wp-block-paragraph">例えば、各要素を2倍にした新しい配列を作りたい場合は次のようにします。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const numbers = [1, 2, 3, 4];
const doubled = numbers.map((num) =&gt; num * 2);
console.log(doubled); // [2, 4, 6, 8]</code></pre></div>



<p class="wp-block-paragraph">ここでは、<code>num * 2</code> の計算結果が新しい配列の各要素となり、<code>doubled</code> は <code>[2, 4, 6, 8]</code> となります。</p>



<h5 class="wp-block-heading">実用的な例</h5>



<p class="wp-block-paragraph">配列内のオブジェクトに対しても <code>map</code> を使うことができます。例えば、ユーザーの名前を大文字に変換して取得したいとします。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const users = [
  { name: &#39;Alice&#39;, age: 25 },
  { name: &#39;Bob&#39;, age: 30 },
  { name: &#39;Charlie&#39;, age: 35 }
];

const upperCaseNames = users.map((user) =&gt; user.name.toUpperCase());
console.log(upperCaseNames); // [&#39;ALICE&#39;, &#39;BOB&#39;, &#39;CHARLIE&#39;]</code></pre></div>



<p class="wp-block-paragraph">この例では、<code>users</code> 配列の各オブジェクトから <code>name</code> プロパティを取得し、大文字に変換した結果を含む新しい配列が <code>upperCaseNames</code> に格納されます。</p>



<h5 class="wp-block-heading">map関数の特徴</h5>



<ul class="wp-block-list">
<li><strong>非破壊的</strong>: <code>map</code> は元の配列を変更せずに、新しい配列を返します。</li>



<li><strong>チェーン可能</strong>: 他のメソッドと組み合わせて、複数の処理を連続して行えます（例えば、<code>filter</code> と <code>map</code> を組み合わせるなど）。</li>
</ul>



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



<p class="wp-block-paragraph"><code>map</code> は必ず配列と同じ長さの新しい配列を返すため、条件によって要素数を変えたい場合は <code>filter</code> メソッドと組み合わせて使うのが一般的です。</p>



<h5 class="wp-block-heading">filterとの違い</h5>



<ul class="wp-block-list">
<li><code>map</code> は全ての要素を処理し、新しい配列を生成する。</li>



<li><code>filter</code> は条件に一致した要素のみを含む新しい配列を返す。</li>
</ul>



<p class="wp-block-paragraph">このように、<code>map</code> 関数を使うと配列を簡単に加工でき、さまざまな場面で役立ちます。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！！詳しい説明ありがとうございます！！せっかくなので、filter関数の復習もしておきたいです！！</p>
</div></div>



<h2 id="rtoc-3"  class="wp-block-heading">filter関数について</h2>



<p class="wp-block-paragraph"><code>filter</code> 関数は、<strong>配列から特定の条件に合う要素を選び出して新しい配列を返す</strong>メソッドです。元の配列は変更されず、条件に合った要素だけを含む新しい配列が返されます。</p>



<p class="wp-block-paragraph"><strong>基本的な使い方</strong></p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const newArray = array.filter((element) =&gt; {
  // 条件に合う場合のみ `true` を返す
  return element &lt; 10;  // 例: 10未満の要素を抽出
});</code></pre></div>



<p class="wp-block-paragraph">この例では、<code>array</code> の中から、<strong>10未満の要素だけ</strong>を抽出して <code>newArray</code> に格納しています。</p>



<h5 class="wp-block-heading"><code>filter</code> 関数の構文</h5>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const newArray = array.filter((element, index, array) =&gt; {
  // 条件式（真偽値を返す）
  return condition;
});</code></pre></div>



<ul class="wp-block-list">
<li><code>element</code>: 配列の現在の要素</li>



<li><code>index</code>: 配列の現在の要素のインデックス（位置）</li>



<li><code>array</code>: 配列そのもの（オプションで使用）</li>
</ul>



<p class="wp-block-paragraph"><code>filter</code> は条件式が <code>true</code> を返す要素だけを新しい配列に追加し、<code>false</code> を返す要素は除外します。</p>



<p class="wp-block-paragraph"><br><strong>例1: 数字の配列から偶数だけを抽出</strong></p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const evenNumbers = numbers.filter((number) =&gt; number % 2 === 0);
console.log(evenNumbers); // [2, 4, 6, 8]</code></pre></div>



<p class="wp-block-paragraph">この例では、配列 <code>numbers</code> から <strong>偶数だけ</strong>を抽出しています。条件式 <code>number % 2 === 0</code> が <code>true</code> である偶数の要素だけが新しい配列 <code>evenNumbers</code> に入ります。</p>



<p class="wp-block-paragraph"><strong>例2: オブジェクトの配列から特定の条件でフィルタリング</strong></p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const foods = [
  { id: 1, name: &quot;ハンバーガー&quot;, price: 800 },
  { id: 2, name: &quot;ステーキ&quot;, price: 1500 },
  { id: 3, name: &quot;サラダ&quot;, price: 600 }
];

const cheapFoods = foods.filter((food) =&gt; food.price &lt;= 1000);
console.log(cheapFoods);
// [
//   { id: 1, name: &quot;ハンバーガー&quot;, price: 800 },
//   { id: 3, name: &quot;サラダ&quot;, price: 600 }
// ]</code></pre></div>



<p class="wp-block-paragraph">この例では、<code>foods</code> 配列から <strong>価格が1000円以下</strong> の食べ物を抽出しています。<code>food.price &lt;= 1000</code> の条件を満たすオブジェクトだけが新しい配列 <code>cheapFoods</code> に入ります。</p>



<h5 class="wp-block-heading">filterメソッドまとめ</h5>



<ul class="wp-block-list">
<li><code>filter</code> は <strong>元の配列を変更せず</strong>、条件に一致する要素だけを抽出して新しい配列を返します。</li>



<li>使い方は簡単で、<code>filter</code> に渡すコールバック関数で条件を指定するだけです。</li>



<li>配列の中身を条件に応じて絞り込みたい場合に便利なメソッドです。</li>
</ul>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">バッチリ分かりました！！復習ありがとうございます！！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">では、それを踏まえた上で下のReactのコードを見てみましょう！！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const foods = [
  { id: 1, name: &quot;ラーメン&quot;, price: 800 },
  { id: 2, name: &quot;カレー&quot;, price: 750 },
  { id: 3, name: &quot;うどん&quot;, price: 600 }
];

const FoodList = () =&gt; {
  return (
    &lt;&gt;
      &lt;h3&gt;メニューリスト&lt;/h3&gt;
      &lt;ul&gt;
        {foods.map((food) =&gt; (
          &lt;li key={food.id}&gt;
            {food.name}は{food.price}円です
          &lt;/li&gt;
        ))}
      &lt;/ul&gt;
    &lt;/&gt;
  );
};</code></pre></div>



<p class="wp-block-paragraph">map関数は3つの部分で構成されています</p>



<ol class="wp-block-list">
<li><code>配列.map()</code> &#8211; 配列に対してmap関数を呼び出します</li>



<li><code>((food) =&gt;</code> &#8211; 配列の各要素を表す引数を第１引数に指定します</li>



<li><code>&lt;li&gt;...&lt;/li&gt;)</code> &#8211; 各要素をどのようにして表示するかを書きます</li>



<li></li>
</ol>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">わかりやすいです！ということは、配列の要素に対して何か処理をしたい場合も、map関数の中で書けるんですね？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">その通りです！例えば、1000円以下のメニューだけに「お買い得」と表示する例を見てみましょう！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const foods = [
  { id: 1, name: &quot;ハンバーガー&quot;, price: 800 },
  { id: 2, name: &quot;ステーキ&quot;, price: 1500 },
  { id: 3, name: &quot;サラダ&quot;, price: 600 },
];

{foods.map((food) =&gt; (
  &lt;li key={food.id}&gt;
    {food.name}は{food.price}円です
    {food.price &lt;= 1000 && &lt;span style={{color: &#39;red&#39;}}&gt; お買い得!&lt;/span&gt;}
  &lt;/li&gt;
))}</code></pre></div>



<p class="wp-block-paragraph"><code>{条件 &amp;&amp; 表示するJSX}</code> の形を使うと、条件が <code>true</code> の場合にのみ JSX がレンダリングされます。<br>このコードで新しく作成される配列は次のようになります。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>[
  &lt;li key=&quot;1&quot;&gt;ハンバーガーは800円です &lt;span style={{color: &#39;red&#39;}}&gt; お買い得!&lt;/span&gt;&lt;/li&gt;,
  &lt;li key=&quot;2&quot;&gt;ステーキは1500円です&lt;/li&gt;,
  &lt;li key=&quot;3&quot;&gt;サラダは600円です &lt;span style={{color: &#39;red&#39;}}&gt; お買い得!&lt;/span&gt;&lt;/li&gt;
]</code></pre></div>



<p class="wp-block-paragraph">これをJSXの{}で囲っているので、この配列が展開されて表示される仕組みです。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！！分かりました！！ありがとうございます！！<br>でも、先生！１つ気になるんですが、このコードで<strong><span class="marker-under">&lt;li&gt;タグに<code>key</code>ってついてる</span></strong>んですけど、これって何のために必要なんですか？</p>
</div></div>



<h2 id="rtoc-4"  class="wp-block-heading">keyが必要な理由</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">よい質問です！今後、<strong><span class="marker-under">Reactでは、リストタグには、必ずキーを設定</span></strong>してください！まず、なぜつけるかを説明するために、Reactの動作の特徴を説明します。<strong><span class="marker-under">Reactは画面を更新する時、前の状態と新しい状態を比較して、変更があった部分だけを更新しようとします</span></strong>。これを『差分検出』と呼びます。そして、keyがないと困ることが起こるんです。簡単な例で説明しましょう！！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const TodoList = () =&gt; {
  const [todos, setTodos] = useState([
    &quot;数学の宿題&quot;,
    &quot;買い物&quot;,
    &quot;部活&quot;
  ]);

  const addTodo = () =&gt; {
    // リストの先頭に「新しいTodo」を追加
    setTodos([&quot;新しいTodo&quot;, ...todos]);
  };

  return (
    &lt;ul&gt;
      {/* &#x274c; keyなしの場合 */}
      {todos.map((todo) =&gt; (
        &lt;li&gt;{todo}&lt;/li&gt;
      )}
    &lt;/ul&gt;
  );
};</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">このコードには問題があります。新しい項目を追加すると、Reactは全ての<code>&lt;li&gt;</code>要素を作り直してしまいます。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">え？なんでですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">Reactは先頭から順に要素を比較していきます。keyがないと、『1番目は違う内容になった、2番目も違う&#8230;』と判断して、全部作り直してしまうんです。</p>



<p class="wp-block-paragraph">でも、keyをつけると&#8230;</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>// &#x2705; 修正後 keyありの場合
const [todos, setTodos] = useState([
  { id: 1, text: &quot;数学の宿題&quot; },
  { id: 2, text: &quot;買い物&quot; },
  { id: 3, text: &quot;部活&quot; }
]);

return (
  &lt;ul&gt;
    {todos.map((todo) =&gt; (
      &lt;li key={todo.id}&gt;{todo.text}&lt;/li&gt;
    ))}
  &lt;/ul&gt;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">こうすると、<strong>Reactは『あ、これは新しい要素が追加されただけで、他の要素は同じものだ！』</strong>とわかるんです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！こうすると、必要な部分だけ更新できるんですね。</p>
</div></div>



<h3 id="rtoc-5"  class="wp-block-heading">keyをつける時の注意点</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">ただし、keyをつける時には3つの重要なルールがあります。</p>
</div></div>



<p class="wp-block-paragraph">１.<strong>リスト内の全ての要素に重複しない名前をつける</strong>必要がある<br>　→※１つの親からぶら下がった子同士の名前が重複しなければOK</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const students = [
  { id: 1, name: &quot;田中&quot; },
  { id: 2, name: &quot;鈴木&quot; },
  { id: 2, name: &quot;佐藤&quot; }  // &#x274c; 同じidは使えません！
];</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">ただし、同じ値のkeyが他のリストにあっても問題ありません。同じ親要素の中で一意であれば大丈夫です。これも下の例を見ておきましょう！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const SchoolRoster = () =&gt; {
  const classA = [
    { number: 1, name: &quot;田中&quot; },
    { number: 2, name: &quot;鈴木&quot; },
    { number: 3, name: &quot;佐藤&quot; }
  ];

  const classB = [
    { number: 1, name: &quot;山田&quot; },
    { number: 2, name: &quot;伊藤&quot; },
    { number: 3, name: &quot;渡辺&quot; }
  ];

  return (
    &lt;div&gt;
      &lt;div&gt;
        &lt;h3&gt;1年A組&lt;/h3&gt;
        &lt;ul&gt;
          {classA.map((student) =&gt; (
            &lt;li key={student.number}&gt;{student.name}&lt;/li&gt;
          )}
        &lt;/ul&gt;
      &lt;/div&gt;
      
      &lt;div&gt;
        &lt;h3&gt;1年B組&lt;/h3&gt;
        &lt;ul&gt;
          {classB.map((student) =&gt; (
            &lt;li key={student.number}&gt;{student.name}&lt;/li&gt;
          )}
        &lt;/ul&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
};</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">あれ？A組もB組も出席番号1から3まで同じ番号を使っていますけど、大丈夫なんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">はい、これは問題ありません！その理由は、それぞれの<code>map</code>が異なる<code>&lt;ul&gt;</code>の中で実行されているからです。</p>
</div></div>



<p class="wp-block-paragraph">つまり：</p>



<ul class="wp-block-list">
<li>A組の<code>&lt;li&gt;</code>要素は、A組の<code>&lt;ul&gt;</code>の中でのみ一意であればOK</li>



<li>B組の<code>&lt;li&gt;</code>要素は、B組の<code>&lt;ul&gt;</code>の中でのみ一意であればOK</li>
</ul>



<p class="wp-block-paragraph">これはツリー構造で考えると分かりやすいです。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-plain"><code>div
├── ul（A組）
│   ├── li (key=1) 田中さん
│   └── li (key=2) 鈴木さん
└── ul（B組）
    ├── li (key=1) 山田さん  // 別の親要素なのでOK
    └── li (key=2) 伊藤さん  // 別の親要素なのでOK</code></pre></div>



<p class="wp-block-paragraph"><strong>2.キーは変更してはいけません</strong></p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>// &#x274c; 良くない例
&lt;li key={Math.random()}&gt;{todo}&lt;/li&gt;

// &#x2705; 良い例
&lt;li key={todo.id}&gt;{todo}&lt;/li&gt;</code></pre></div>



<p class="wp-block-paragraph"><strong>3.配列のインデックスはなるべく使わない</strong></p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>// &#x274c; あまり良くない例
{todos.map((todo, index) =&gt; (
  &lt;li key={index}&gt;{todo}&lt;/li&gt;
))}

// &#x2705; 良い例
{todos.map(todo =&gt; (
  &lt;li key={todo.id}&gt;{todo}&lt;/li&gt;
))}</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><strong><span class="marker-under-blue">インデックスを使うと、配列の要素を並べ替えたり、途中に挿入したりした時に、同じ内容なのにkeyが変わってしまう</span></strong>んです。</p>



<p class="wp-block-paragraph">できるだけ、各項目を一意に特定できるID（データベースのID、商品コードなど）をkeyとして使うことをお勧めします！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！！分かりました！！今日も勉強になりました！！ありがとうございます！</p>
</div></div>



<h2 id="rtoc-6"  class="wp-block-heading">map関数補足：配列を返すのに、どうして表示される？</h2>



<p class="wp-block-paragraph">私がmap関数をReactで最初学習したときに出た疑問ですが、map関数は、新しい配列を返す関数なのだから、「配列が返されてるだけだから、表示されないのでは？」と思っていました。<br><br>この疑問に関しては、<strong><span class="marker-under">JavaScriptのmap関数は確かに新しい配列を返しますが、JSXの中でmap関数を使用する場合、Reactの特別な処理</span></strong>として、<strong><span class="marker-under-red">JSX内では、配列を展開して処理</span></strong>します。つまり、下記のようなコードを書いたとすると、</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code> {[&lt;li&gt;サッカー&lt;/li&gt;, &lt;li&gt;野球&lt;/li&gt;, &lt;li&gt;バスケ&lt;/li&gt;]}</code></pre></div>



<p class="wp-block-paragraph">自動的に以下のように解釈されます。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code> &lt;li&gt;サッカー&lt;/li&gt;
 &lt;li&gt;野球&lt;/li&gt;
 &lt;li&gt;バスケ&lt;/li&gt;</code></pre></div>



<p class="wp-block-paragraph">このReactの特性を押させておきましょう。</p>



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



<p class="wp-block-paragraph">Reactで配列のデータを表示する際には、map関数を使うと便利です。map関数を使うことで、コードをすっきりと記述でき、配列の要素が増えたり減ったりしても簡単に対応できます。また、Reactではリスト要素にkeyを付けることが重要です。keyは、リストの更新を効率よく行うために必要で、特に重複しない一意な値を使うことが推奨されます。この記事では、keyの役割やmap関数の使い方について具体例を交えて解説しました。Reactのリスト表示で迷わないように、ぜひ参考にしてください！</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://oz006.com/react-map-key/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>React入門第８回~Stateとは？~</title>
		<link>https://oz006.com/react-state/</link>
					<comments>https://oz006.com/react-state/#respond</comments>
		
		<dc:creator><![CDATA[oz]]></dc:creator>
		<pubDate>Thu, 14 Nov 2024 01:58:03 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<guid isPermaLink="false">https://oz006.com/?p=431</guid>

					<description><![CDATA[Contents Stateとは？ useStateの役割と使い方 Stateの仕組みをイラストでイメージ useStateの使い方と注意点 1.コンポーネントの中で呼び出す 値の更新と再レンダリングは予約（非同期）され [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="1000" src="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp" alt="" class="wp-image-385" srcset="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp 1000w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-300x300.webp 300w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-150x150.webp 150w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-768x768.webp 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame2 preset6 animation-fade rtoc_open default" data-id="431" data-theme="Cocoon Child">
			<div id="rtoc-mokuji-title" class=" rtoc_left">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">Stateとは？</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-2">useStateの役割と使い方</a></li></ul></li><li class="rtoc-item"><a href="#rtoc-3">Stateの仕組みをイラストでイメージ</a></li><li class="rtoc-item"><a href="#rtoc-4">useStateの使い方と注意点</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-5">1.コンポーネントの中で呼び出す</a></li><li class="rtoc-item"><a href="#rtoc-6">値の更新と再レンダリングは予約（非同期）される</a></li><li class="rtoc-item"><a href="#rtoc-7">前回のstate値を使用する場合は更新関数に関数を渡す</a></li><li class="rtoc-item"><a href="#rtoc-8">オブジェクト型のstateを更新する際には新しいオブジェクトを作成する</a></li><li class="rtoc-item"><a href="#rtoc-9">stateの値はコンポーネントごとに独立して管理される</a></li><li class="rtoc-item"><a href="#rtoc-10">一度消滅したコンポーネントのstateの値はリセットされる</a></li><li class="rtoc-item"><a href="#rtoc-11">stateをpropsとして渡すことで子コンポーネントで利用可能</a></li><li class="rtoc-item"><a href="#rtoc-12">コンポーネントの位置によってはstateが維持される</a></li></ul></li><li class="rtoc-item"><a href="#rtoc-13">まとめ</a></li></ol></div><h2 id="rtoc-1"  class="wp-block-heading">Stateとは？</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="プロ太" class="speech-icon-image"/></figure><div class="speech-name">プロ太</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">OZくん、今日はReactの<strong><span class="marker-under">State</span></strong>について学んでいきましょう！超重要です！！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="OZ" class="speech-icon-image"/></figure><div class="speech-name">OZ</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">State？？何ですか？なんとなく重要そうだけど…。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">Reactでは、<strong>コンポーネントが画面に表示される内容を管理</strong>してるんですが、この<strong><span class="marker-under">State</span><span class="marker-under">は</span><span class="marker-under">、</span><span class="marker-under">コンポーネント</span><span class="marker-under">の</span><span class="marker-under">中で</span><span class="marker-under">変化するデータを保持するために必要</span></strong>なんです！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど…<strong>例えば、入力欄に文字を打ったときに表示が変わる</strong>ような状況で、Stateは必要なんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">その通り！！<strong>Stateがなければ、入力した文字がReactに伝わらず、画面に反映されない</strong>んです。ちょっと簡単な例で説明してみますね！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const Example = () =&gt; {
  let displayVal; // 表示用の変数を用意

  return (
    &lt;input
      type=&quot;text&quot;
      onChange={(e) =&gt; {
        displayVal = e.target.value; // 入力された値をdisplayValに代入
        console.log(displayVal); // 値をコンソールに表示して確認
      }}
    /&gt;
  );
};

export default Example;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">あれ？このコードでは<code>displayVal</code>に入力した値を入れてるけど、これだけだと画面が変わらないんですね？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうなんです。<strong><span class="marker-under">Reactが画面の再レンダリングをするためには、Stateを使って<code>displayVal</code>を管理する必要がある</span></strong>んです。さっきのコードでは、<strong><span class="marker-under"><code>displayVal</code>が変更されてもReactにはその情報が伝わらない</span></strong>んです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">じゃあ、どうやってReactに伝えるんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">それが次のテーマである<strong>useState</strong>関数なんです。<code>useState</code>を使うと、<strong>Reactに状態を管理させる</strong>ことができるんです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">状態を管理…？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">簡単に言うと、<strong><span class="marker-under"><code>useState</code>を使えば、値が変わったときにReactが自動で画面を更新してくれる</span></strong>んです。使うためには、先程のコードを、以下のように書き換えられます。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>import { useState } from &#39;react&#39;;

const Example = () =&gt; {
  const [displayVal, setDisplayVal] = useState(&#39;&#39;); // 初期値は空文字

  return (
    &lt;input
      type=&quot;text&quot;
      onChange={(e) =&gt; {
        setDisplayVal(e.target.value); // 値を更新関数で変更
      }}
      value={displayVal} // 表示される値もdisplayValに依存
    /&gt;
  );
};

export default Example;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">おお！<code>useState</code>の中にある<code>setDisplayVal</code>を使うと、自動でReactが画面を再表示してくれるんですね！！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうです！これで、ユーザーが入力した内容がリアルタイムで画面に反映されるようになるんです。<code>useState</code>関数の仕組みについては、次に詳しく見てみましょう！！</p>
</div></div>



<h3 id="rtoc-2"  class="wp-block-heading">useStateの役割と使い方</h3>



<ol class="wp-block-list">
<li><strong>接続 (Hook into)</strong>
<ul class="wp-block-list">
<li><code>useState</code>を使うと、React内部でその状態が管理されるようになります<br>これを「Hook into」と呼んでいます</li>
</ul>
</li>



<li><strong>現在の値と更新関数の返却</strong>
<ul class="wp-block-list">
<li><code>useState</code>は「現在の値」と「更新関数」の2つを返してくれます。さっきのコードでいうと、<code>displayVal</code>が現在の値、<code>setDisplayVal</code>が更新関数です</li>
</ul>
</li>



<li><strong>再レンダリングのトリガー</strong>
<ul class="wp-block-list">
<li>更新関数<code>setDisplayVal</code>を使って値を変えると、Reactが自動的にその変更を画面に反映してくれています</li>
</ul>
</li>
</ol>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！<strong><span class="marker-under"><code>useState</code>を使えば、Reactが自動的に画面を更新してくれるから、値を保持するのも簡単だし、ユーザーの操作に合わせて反映させるのも楽になる</span></strong>んですね！今から帰って実際に使ってみます！！ありがとうございました！</p>
</div></div>



<h2 id="rtoc-3"  class="wp-block-heading">Stateの仕組みをイラストでイメージ</h2>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="750" src="https://oz006.com/wp-content/uploads/2024/11/IMG_4615.jpg" alt="" class="wp-image-450" srcset="https://oz006.com/wp-content/uploads/2024/11/IMG_4615.jpg 1000w, https://oz006.com/wp-content/uploads/2024/11/IMG_4615-300x225.jpg 300w, https://oz006.com/wp-content/uploads/2024/11/IMG_4615-768x576.jpg 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="750" src="https://oz006.com/wp-content/uploads/2024/11/IMG_4616.jpg" alt="" class="wp-image-451" srcset="https://oz006.com/wp-content/uploads/2024/11/IMG_4616.jpg 1000w, https://oz006.com/wp-content/uploads/2024/11/IMG_4616-300x225.jpg 300w, https://oz006.com/wp-content/uploads/2024/11/IMG_4616-768x576.jpg 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="750" src="https://oz006.com/wp-content/uploads/2024/11/IMG_4617.jpg" alt="" class="wp-image-452" srcset="https://oz006.com/wp-content/uploads/2024/11/IMG_4617.jpg 1000w, https://oz006.com/wp-content/uploads/2024/11/IMG_4617-300x225.jpg 300w, https://oz006.com/wp-content/uploads/2024/11/IMG_4617-768x576.jpg 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="750" src="https://oz006.com/wp-content/uploads/2024/11/IMG_4618.jpg" alt="" class="wp-image-453" srcset="https://oz006.com/wp-content/uploads/2024/11/IMG_4618.jpg 1000w, https://oz006.com/wp-content/uploads/2024/11/IMG_4618-300x225.jpg 300w, https://oz006.com/wp-content/uploads/2024/11/IMG_4618-768x576.jpg 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="750" src="https://oz006.com/wp-content/uploads/2024/11/IMG_4619.jpg" alt="" class="wp-image-454" srcset="https://oz006.com/wp-content/uploads/2024/11/IMG_4619.jpg 1000w, https://oz006.com/wp-content/uploads/2024/11/IMG_4619-300x225.jpg 300w, https://oz006.com/wp-content/uploads/2024/11/IMG_4619-768x576.jpg 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<h2 id="rtoc-4"  class="wp-block-heading">useStateの使い方と注意点</h2>



<p class="wp-block-paragraph">数日後、、、</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-12 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ02.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">プロ太先生、あれから、<strong><span class="marker-under-blue">ReactでuseStateを使ってみてるんですけど、エラーが出たり、思った通りに動かなかったりして</span></strong>困ってます。何か使い方にコツがあるんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">useStateにはいくつか気をつけるポイントがあります。それを知っておくと、Reactの状態管理がもっと分かりやすくなりますよ！説明しますね。</p>
</div></div>



<h3 id="rtoc-5"  class="wp-block-heading">1.コンポーネントの中で呼び出す</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">まず、<strong><span class="marker-under">useStateは必ずコンポーネントの中で使わないといけない</span></strong>んです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><strong>コンポーネントの中って、つまり <code>function Example() { ... }</code> の中</strong>ですよね？<br>他の場所では使えないんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">使えません。useStateはReactのフック（Hooks）の一つなんですが、Reactのフックは、Reactコンポーネントの中でのみ動作するように作られているんです。<strong><span class="marker-under">もしコンポーネントの外や、ループや条件分岐の中で呼び出してしまうとエラー</span></strong>になるんですよ。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なんでエラーが出るんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">ReactはuseStateを使うコンポーネントを再レンダリングするたびに、同じ順番でフックが呼ばれるように管理しているんだ。もしif文の中でuseStateを呼ぶと、条件によって呼ばれる順番が変わる可能性があるから、エラーになってしまうんです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど、だからコンポーネントのトップレベルで使うのが基本なんですね！</p>
</div></div>



<h3 id="rtoc-6"  class="wp-block-heading">値の更新と再レンダリングは予約（非同期）される</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">次の注意点はですね、useStateのset関数を使ってstateを更新すると、<strong><span class="marker-under">その変更はすぐには画面に反映されない</span></strong>んです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">えっ？どういうことですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">Reactはstateの変更を‘予約’するんです。つまり、<strong><span class="marker-under">setCount(count + 1)と書いても、すぐにcountの値が画面に反映されるわけじゃなくて、次の再レンダリングが発生するタイミングで更新</span></strong>されるんです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">へぇ、非同期なんですね！それは、Reactが効率よくレンダリングを管理するための仕組みなんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうです！Reactはパフォーマンスを重視しているから、無駄に再レンダリングをしないように、必要なタイミングでまとめて画面を更新してくれるんだ。ちょっと、コードで例を見てみましょう！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>import React, { useState } from &#39;react&#39;;

function Counter() {
  const [count, setCount] = useState(0);

  const handleClick = () =&gt; {
    console.log(&quot;クリック前のcount:&quot;, count);
    setCount(count + 1);
    console.log(&quot;クリック後のcount:&quot;, count);
  };

  return (
    &lt;div&gt;
      &lt;p&gt;現在のカウント: {count}&lt;/p&gt;
      &lt;button onClick={handleClick}&gt;カウントを増やす&lt;/button&gt;
    &lt;/div&gt;
  );
}

export default Counter;
</code></pre></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="356" height="214" src="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-14-8.54.19.png" alt="" class="wp-image-455" srcset="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-14-8.54.19.png 356w, https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-14-8.54.19-300x180.png 300w" sizes="auto, (max-width: 356px) 100vw, 356px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="294" height="172" src="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-14-8.58.33.png" alt="" class="wp-image-456"/></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="314" height="114" src="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-14-8.58.39.png" alt="" class="wp-image-457" srcset="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-14-8.58.39.png 314w, https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-14-8.58.39-300x109.png 300w" sizes="auto, (max-width: 314px) 100vw, 314px" /></figure>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">このコードで、<code>&lt;button&gt;</code>をクリックすると<code>count</code>が増えるんですよね？<br>でも、<code>handleClick</code>の中の<code>console.log</code>で<code>count</code>を表示しているのに、なんでボタンをクリックしても<strong><code>console.log</code>で<code>count</code>が変わらない</strong>んですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">実は、<code>setCount(count + 1)</code>を呼んでも、即座に<code>count</code>の値が更新されるわけじゃないんです。さっきも言った通り、Reactは変更を予約して、次の再レンダリング時（returnで出力する時）に新しい値を反映するんです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">つまり、<code>setCount(count + 1)</code>を呼んだ直後の<code>console.log("クリック後のcount:", count);</code>ではreturnの前で、まだ<code>count</code>が変わっていないから、同じ値が表示されるってことなんですね？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">その通り！実際に画面の表示が更新されるのは、次のレンダリング（return）が行われるときです。だから、直後の<code>console.log</code>には反映されません。でも、新しい<code>count</code>の値は次の再レンダリング(return）で表示されるようになります。これが、Stateの注意点の１つです。</p>
</div></div>



<h3 id="rtoc-7"  class="wp-block-heading">前回のstate値を使用する場合は更新関数に関数を渡す</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">ところで、<strong><span class="marker-under">状態を更新するときに前の値を使いたい場合</span></strong>もありますよね？<br>例えば、<code>count</code> を1ずつ増やしたいときとか。その場合、<code>setCount(count + 1);</code> と書いても、うまくいかないことがあるんです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">えっ、なんでですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">さっきも言ったように、stateの更新は非同期的に行われるから、countの現在の値を直接使って更新すると、意図しない動作になることがあります。そんなときは、<strong><span class="marker-under">前の値を使って新しい値を計算するように、関数を渡す</span></strong>といいです。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>setCount((prevCount) =&gt; prevCount + 1);</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！これなら <code>prevCount</code> に前の <code>count</code> の値が入っているから、確実に1ずつ増やせるんですね！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">その通り！<strong>特にボタンを連打するような状況では、これを使わないと予期しない結果になることが多い</strong>ので、覚えておくといいですよ。</p>
</div></div>



<h3 id="rtoc-8"  class="wp-block-heading">オブジェクト型のstateを更新する際には新しいオブジェクトを作成する</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">じゃあ、user という<strong><span class="marker-under">オブジェクトを state として使う例</span></strong>を見てみよう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const [user, setUser] = useState({ name: &quot;OZ&quot;, age: 17 });</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">ここで、user の <code>name</code> プロパティだけを更新したい場合、 <strong><span class="marker-under-red"><code>user.name = '新しい名前'</code> と直接書き換えたくなるかも</span></strong>しれませんよね。でも、これはやっちゃいけません。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">どうしてですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><strong>React は state が変更されたことを検知して再レンダリングを行う仕組み</strong>なんだけど、<strong><span class="marker-under-blue">state のオブジェクトを直接変更すると、React がその変更をうまく認識できない</span></strong>んです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど…じゃあ、どうすればいいんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そこで、<strong>新しいオブジェクトを作成して、それを <code>setUser</code> 関数に渡す必要</strong>があります。このとき、<code>...prevUser</code> というのが出てくるんです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">え、<code>...prevUser</code> ってどういう意味なんですか？</p>
</div></div>



<h4 class="wp-block-heading">スプレッド構文 (<code>...</code>) の意味を詳しく説明</h4>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">この <code>...prevUser</code> はスプレッド構文と呼ばれるもので、オブジェクトの内容を展開する役割があります。たとえば、<code>user</code> が <code>{ name: 'OZ', age: 17 }</code> というオブジェクトだとすると、<code>...prevUser</code> と書くと、<code>user</code> オブジェクトの中身が <code>{ name: 'OZ', age: 17 }</code> として展開されるんだよ。つまり、スプレッド構文を使うと、オブジェクトのすべてのプロパティがコピーされます。実際のコードも見ておきましょう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>setUser((prevUser) =&gt; ({ ...prevUser, name: &#39;新しい名前&#39; }));</code></pre></div>



<p class="wp-block-paragraph">ここで何が起きているかを分解してみると、</p>



<ol class="wp-block-list">
<li><strong><code>prevUser</code></strong>: <code>setUser</code> に渡される関数の引数 <code>prevUser</code> は、現在の <code>user</code> の状態を表すオブジェクトです。つまり、 <code>{ name: 'OZ', age: 17 }</code> です。</li>



<li><strong><code>{ ...prevUser }</code></strong>: スプレッド構文 (<code>...prevUser</code>) を使って <code>prevUser</code> の中身を新しいオブジェクトに展開しています。これにより、新しいオブジェクトが <code>{ name: 'OZ', age: 17 }</code> として作成されます。</li>



<li><strong><code>name: '新しい名前'</code></strong>: 新しいオブジェクトに <code>{ name: '新しい名前' }</code> というプロパティを追加しています。このとき、元々の <code>name: 'OZ'</code> が上書きされ、新しい <code>name</code> の値が <code>'新しい名前'</code> になります。</li>
</ol>



<p class="wp-block-paragraph">最終的に、次のようなオブジェクトが <code>setUser</code> に渡されます。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>{ name: &#39;新しい名前&#39;, age: 17 }</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど、だから <code>setUser</code> に渡されるのは <code>age</code> がそのままで、<code>name</code> だけが変わった新しいオブジェクトなんですね！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうです！新しいオブジェクトを作成することで、React が state の変更を認識して、必要に応じて再レンダリングを行ってくれるんです。</p>
</div></div>



<h3 id="rtoc-9"  class="wp-block-heading">stateの値はコンポーネントごとに独立して管理される</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">次に、stateはコンポーネントごとに独立していることも覚えておきましょう。<br>たとえば、<code>Example</code> というコンポーネントが2つあるとします。それぞれに <code>count</code> というstateがあっても、片方の <code>count</code> を更新してももう片方には影響しません。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！同じコンポーネントでも別々の状態を持つことができるんですね！</p>
</div></div>



<h3 id="rtoc-10"  class="wp-block-heading">一度消滅したコンポーネントのstateの値はリセットされる</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">じゃあ、モーダルみたいに、表示を消してもう一度表示した場合、stateはどうなるんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">もし条件分岐でコンポーネントを一時的に非表示にして、再度表示させた場合、そのコンポーネントのstateは初期化されてしまいます。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！モーダルを一度閉じて再度開いたときに、入力内容がリセットされるのもそのためなんですね。</p>
</div></div>



<h3 id="rtoc-11"  class="wp-block-heading">stateをpropsとして渡すことで子コンポーネントで利用可能</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">親コンポーネントで定義した <code>state</code> は、そのまま親コンポーネントの中だけで使うこともできるんだけど、<code>props</code> を使って子コンポーネントにも渡して利用することができますよ。具体的なコードを見てみましょう。</p>
</div></div>



<p class="wp-block-paragraph">まず、親コンポーネントで <code>count</code> という <code>state</code> を定義します。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>import { useState } from &quot;react&quot;;
import ChildComponent from &quot;./Childcomponent&quot;;

function ParentComponent() {
  const [count, setCount] = useState(0);
  const incrementCount = () =&gt; setCount(count + 1);

  return (
    &lt;div&gt;
      &lt;h1&gt;現在のカウント： {count}&lt;/h1&gt;
      &lt;ChildComponent count={count} /&gt;
      &lt;button onClick={incrementCount}&gt;ボタン&lt;/button&gt;
    &lt;/div&gt;
  );
}

export default ParentComponent;</code></pre></div>



<p class="wp-block-paragraph">このコードのポイントは、<code>&lt;ChildComponent count={count} /&gt;</code> という部分です。ここで <code>count={count}</code> として、<code>count</code> の <code>state</code> を <code>props</code> として子コンポーネントに渡しています。</p>



<h4 class="wp-block-heading">子コンポーネントで <code>props</code> を受け取る</h4>



<p class="wp-block-paragraph">次に、子コンポーネント側で <code>count</code> を使えるようにします。<code>ChildComponent</code> は次のようになります。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>import React from &#39;react&#39;;

function ChildComponent({ count }) {
  return (
    &lt;div&gt;
      &lt;p&gt;子コンポーネントでのカウント: {count}&lt;/p&gt;
    &lt;/div&gt;
  );
}

export default ChildComponent;</code></pre></div>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="親コンポーネントから、propsでStateを渡して子コンポーネントで使用！" width="1256" height="707" src="https://www.youtube.com/embed/VKBTIn6I3gk?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p class="wp-block-paragraph">このコードでは、<code>{ count }</code> という記述で <code>props</code> の <code>count</code> を受け取っています。<code>props</code> は通常、<code>props.count</code> としてアクセスできますが、ここでは JavaScript の「分割代入（destructuring）」という書き方を使って、<code>count</code> だけを直接取り出して使っています。</p>



<h5 class="wp-block-heading">親から子にデータが流れる仕組み</h5>



<ol class="wp-block-list">
<li><strong>親コンポーネントで <code>state</code> を定義</strong>: <code>ParentComponent</code> で <code>count</code> を <code>useState</code> で管理しています。</li>



<li><strong><code>props</code> として子コンポーネントに渡す</strong>: <code>ParentComponent</code> の中で、<code>&lt;ChildComponent count={count} /&gt;</code> として、<code>count</code> を <code>props</code> として <code>ChildComponent</code> に渡しています。</li>



<li><strong>子コンポーネントで <code>props</code> を受け取って表示</strong>: <code>ChildComponent</code> は、親から渡された <code>props</code> の <code>count</code> を受け取って、<code>子コンポーネントでのカウント: {count}</code> として画面に表示しています。</li>
</ol>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！これで、親コンポーネントで管理している <code>count</code> のデータを、子コンポーネントでも使えるようになるんですね。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうです！これが、React で <code>state</code> を共有する基本的な方法です。親から子に <code>props</code> を通してデータが流れることで、親の <code>state</code> を変更すれば、子コンポーネントでもその変化が反映されるようになります。</p>
</div></div>



<h3 id="rtoc-12"  class="wp-block-heading">コンポーネントの位置によってはstateが維持される</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">あと、覚えておいてほしいのは、Reactで特定の条件によってコンポーネントを表示・非表示にするときに、<strong><span class="marker-under"><code>key</code>属性がないと、再レンダリングされたときにstateがリセットされる場合がある</span></strong>ことです。</p>
</div></div>



<h4 class="wp-block-heading">状態を維持するためのコードの書き方</h4>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">例えば、<span class="marker-under-red"><strong>フォームに入力していた内容が突然消えたり、カウントしていた数がリセットされたりしたら困ります</strong></span>よね？条件付きでコンポーネントを表示・非表示にする場合、<code>key</code>属性を設定することで、Reactはそのコンポーネントを同一のものとして認識してくれます。これにより、状態が保持されるようになるんです。実際のコードで見てみましょう！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>import { useState } from &quot;react&quot;;

function Counter() {
  const [count, setCount] = useState(0);

  return (
    &lt;div&gt;
      &lt;h2&gt;カウント：{count}&lt;/h2&gt;
      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;カウントを増やす&lt;/button&gt;
    &lt;/div&gt;
  );
}

function App() {
  const [showCounter, setShowCounter] = useState(true);

  return (
    &lt;div&gt;
      &lt;button onClick={() =&gt; setShowCounter(!showCounter)}&gt;
        カウンターを{showCounter ? &quot;隠す&quot; : &quot;表示する&quot;}
      &lt;/button&gt;
      {showCounter && &lt;Counter /&gt;}
    &lt;/div&gt;
  );
}

export default App;</code></pre></div>



<h5 class="wp-block-heading">コードの説明</h5>



<ol class="wp-block-list">
<li><strong><code>Counter</code>コンポーネント</strong>:
<ul class="wp-block-list">
<li><code>Counter</code>は<code>count</code>という状態を持ち、ボタンを押すとカウントが増える仕組みになっています。</li>
</ul>
</li>



<li><strong><code>App</code>コンポーネント</strong>:
<ul class="wp-block-list">
<li><code>showCounter</code>という状態を持ち、<code>showCounter</code>が<code>true</code>のときだけ<code>Counter</code>コンポーネントを表示します。</li>



<li>「カウンターを隠す／表示する」ボタンで<code>showCounter</code>の値をトグルすることで、<code>Counter</code>を表示・非表示に切り替えます。</li>
</ul>
</li>
</ol>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="表示・非表示によるStateのリセット" width="1256" height="707" src="https://www.youtube.com/embed/5a_kRO-hf2I?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h5 class="wp-block-heading">状態がリセットされる問題</h5>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-12 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ02.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">これを実行すると、<code>Counter</code>コンポーネントを隠してもう一度表示すると、カウントがリセットされちゃいますね。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうです。<code>Counter</code>コンポーネントを一度非表示にすると、そのコンポーネントがDOMから削除されるので、もう一度表示すると新しいインスタンスとして再生成されてしまい、カウントも初期値に戻ります。</p>
</div></div>



<h5 class="wp-block-heading">解決策：コード修正</h5>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>import { useState } from &quot;react&quot;;

function Counter({ count, countIncrement }) {
  return (
    &lt;div&gt;
      &lt;h2&gt;カウント：{count}&lt;/h2&gt;
      &lt;button onClick={countIncrement}&gt;カウントを増やす&lt;/button&gt;
    &lt;/div&gt;
  );
}

function App() {
  const [count, setCount] = useState(0);
  const [showCounter, setShowCounter] = useState(true);

  const countIncrement = () =&gt; {
    setCount(count + 1);
  };
  return (
    &lt;div&gt;
      &lt;button onClick={() =&gt; setShowCounter(!showCounter)}&gt;
        カウンターを{showCounter ? &quot;隠す&quot; : &quot;表示する&quot;}
      &lt;/button&gt;
      {showCounter && &lt;Counter count={count} countIncrement={countIncrement} /&gt;}
    &lt;/div&gt;
  );
}

export default App;</code></pre></div>



<p class="wp-block-paragraph">主な変更点は以下になります。</p>



<ol class="wp-block-list">
<li>カウントの状態（<code>count</code>）を<code>App</code>コンポーネントに移動</li>



<li><code>Counter</code>コンポーネントを制御コンポーネントに変更し、以下のpropsを受け取るように変更
<ul class="wp-block-list">
<li><code>count</code>: 現在のカウント値</li>



<li><code>onIncrement</code>: カウントを増やすための関数</li>
</ul>
</li>
</ol>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="カウンターの保持・成功" width="1256" height="707" src="https://www.youtube.com/embed/UbQntSQh4Gc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">おお〜！！カウントが保存されてる！！これは色んな場面で使えそうですね！！<br>プロ太先生！ありがとうございました！！useStateを使う上で注意すべきポイントがよく分かりました！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">どういたしまして！これを意識しながら、実際にコードを書いてみるともっと理解が深まるはずだよ。Reactのstate管理をマスターすれば、もっと便利にアプリが作れるようになるので、ぜひ頑張ってくださいね！</p>
</div></div>



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



<p class="wp-block-paragraph">今回の記事の主なポイント、</p>



<ol class="wp-block-list">
<li>useStateの基本概念と必要性
<ul class="wp-block-list">
<li>コンポーネント内で変化するデータの管理</li>



<li>画面の自動更新との連携</li>
</ul>
</li>



<li>useStateの重要な特徴
<ul class="wp-block-list">
<li>コンポーネント内でのみ使用可能</li>



<li>状態更新は非同期で行われる</li>



<li>コンポーネントごとに独立した状態管理</li>
</ul>
</li>



<li>実践的な使用方法
<ul class="wp-block-list">
<li>前回のstate値を使用する場合の正しい更新方法</li>



<li>オブジェクト型のstate更新時の注意点</li>



<li>propsを使った親子コンポーネント間のstate共有</li>
</ul>
</li>



<li>よくある課題と解決策
<ul class="wp-block-list">
<li>コンポーネントの表示/非表示時のstate維持方法</li>



<li>親コンポーネントでのstate管理による解決策</li>



<li>状態を保持するためのコードの書き方の例</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://oz006.com/react-state/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>React入門第７回~開発でよく使うイベントタイプ~</title>
		<link>https://oz006.com/react-ivent-type/</link>
					<comments>https://oz006.com/react-ivent-type/#respond</comments>
		
		<dc:creator><![CDATA[oz]]></dc:creator>
		<pubDate>Tue, 12 Nov 2024 01:22:02 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<guid isPermaLink="false">https://oz006.com/?p=427</guid>

					<description><![CDATA[Reactのイベントハンドリングを理解しよう clickHandler関数は、ボタンがクリックされたときにalertを表示するものです。一方で、clickHandler2関数は、クリック時にconsole.logでメッセ [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="1000" src="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp" alt="" class="wp-image-385" srcset="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp 1000w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-300x300.webp 300w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-150x150.webp 150w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-768x768.webp 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<h2 id="rtoc-1"  class="wp-block-heading">Reactのイベントハンドリングを理解しよう</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="OZ" class="speech-icon-image"/></figure><div class="speech-name">OZ</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">プロ太先生！！Reactのアプリケーションを開発する上で、<strong><span class="marker-under">ユーザーからの入力やアクションに対応することが重要</span></strong>だと聞きました！！具体的にはどんなふうに対応すればいいんですか?</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="プロ太" class="speech-icon-image"/></figure><div class="speech-name">プロ太</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">Reactでは<strong><span class="marker-under">DOM Eventsと同様のイベントシステムを提供しており、様々なイベントタイプを活用してユーザーの操作を検知し、それに応じた処理を行う</span></strong>ことができます。まずは、<strong>ボタンがクリックされた時の処理</strong>を見てみましょう。こんなふうに書けます。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const Example = () =&gt; {
  const clickHandler = () =&gt; {
    alert(&#39;ボタンがクリックされました。&#39;);
  }
  
  const clickHandler2 = () =&gt; {
    console.log(&#39;ボタンがクリックされました。&#39;);
  }

  return (
    &lt;&gt;
      &lt;button onClick={clickHandler}&gt;クリックしてね&lt;/button&gt;
      &lt;button onClick={clickHandler2}&gt;クリックしてね&lt;/button&gt;
    &lt;/&gt;
  );
};</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">おぉ！これなら、JSの勉強したのでなんとなく分かりそうです！<br><strong>2つのボタンがあって、それぞれのボタンのクリック時に<code>alert</code>と<code>console.log</code>が呼び出されている</strong>みたいですね！！こんな感じであってますか?</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうです！OZくん！このコードでは、ボタンのクリックイベントにハンドラを定義しています！</p>
</div></div>



<p class="wp-block-paragraph"><code>clickHandler</code>関数は、ボタンがクリックされたときに<code>alert</code>を表示するものです。<br>一方で、<code>clickHandler2</code>関数は、クリック時に<code>console.log</code>でメッセージを出力するものになっています。</p>



<p class="wp-block-paragraph">そして、これらのイベントハンドラの関数をボタンの<code>onClick</code>プロパティに直接指定することで、ボタンがクリックされたときに適切な処理が実行されるようになっています。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="プロ太" class="speech-icon-image"/></figure><div class="speech-name">プロ太</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">Reactでは、このようにイベントハンドラの関数を直接指定することで、ユーザーの操作に応じた処理を行うことができます。これが、Reactのイベントハンドリングの基本的な使い方になります。では次に、<strong>入力フィールドに関するイベントハンドリング</strong>を見ていきましょう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const InputEvents = () =&gt; {
  return (
    &lt;div&gt;
      &lt;h3&gt;コンソールを確認してください。&lt;/h3&gt;
      &lt;label&gt;
        入力値のイベント：
        &lt;input
          type=&quot;text&quot;
          onChange={() =&gt; console.log(&quot;onChange検知&quot;)}
          onBlur={() =&gt; console.log(&quot;onBlur検知&quot;)}
          onFocus={() =&gt; console.log(&quot;onFocus検知&quot;)}
        /&gt;
      &lt;/label&gt;
      &lt;div&gt;
        &lt;label&gt;
          入力値を取得：
          &lt;input type=&quot;text&quot; onChange={(e) =&gt; console.log(e.target.value)} /&gt;
        &lt;/label&gt;
      &lt;/div&gt;
      &lt;div
        className=&quot;hover-event&quot;
        onMouseEnter={() =&gt; console.log(&quot;カーソルが入ってきました。&quot;)}
        onMouseLeave={() =&gt; console.log(&quot;カーソルが出ていきました。&quot;)}
      &gt;
        ホバーしてね！
      &lt;/div&gt;
    &lt;/div&gt;
  );
};</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">ここでは、<code>o</code><strong><span class="marker-under"><code>nChange</code>、<code>onBlur</code>、<code>onFocus</code>といったイベントを使って、ユーザーの入力操作を検知</span></strong>しています。また、<strong><span class="marker-under"><code>e.target.value</code>を使うことで、入力値を取得</span></strong>できますね。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど、Reactのイベントハンドリングの基本はこんな感じなんですね。具体的な使い方がよくわかりました！ありがとうございました！！</p>
</div></div>



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



<p class="wp-block-paragraph">Reactのイベントハンドリングでは、ユーザーの操作に応じた様々な反応を作り出すことができます。この投稿では、<strong><span class="marker-under">ボタンのクリックや入力フィールドのonChange、onBlur、onFocusイベント、ホバーイベントなど、基本的なイベントハンドリングの使い方を解説</span></strong>しました。イベントハンドラを設定することで、ユーザーの操作に対応する柔軟なインタラクションが実現できます。基本を押さえ、より豊かなReactアプリを作っていきましょう！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://oz006.com/react-ivent-type/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>React入門第６回~JSXの正体を探ろう！~</title>
		<link>https://oz006.com/jsx-babel-virtualdom/</link>
					<comments>https://oz006.com/jsx-babel-virtualdom/#respond</comments>
		
		<dc:creator><![CDATA[oz]]></dc:creator>
		<pubDate>Sun, 10 Nov 2024 04:13:58 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<guid isPermaLink="false">https://oz006.com/?p=424</guid>

					<description><![CDATA[Contents JSXの正体とは？ Babelが行っていること 仮想DOMとは？ まとめ JSXの正体とは？ Babelが行っていること 実際にもう少し複雑な例を見てみましょう！ 仮想DOMとは？ まとめ]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="1000" src="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp" alt="" class="wp-image-385" srcset="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp 1000w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-300x300.webp 300w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-150x150.webp 150w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-768x768.webp 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame2 preset6 animation-fade rtoc_open default" data-id="424" data-theme="Cocoon Child">
			<div id="rtoc-mokuji-title" class=" rtoc_left">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">JSXの正体とは？</a></li><li class="rtoc-item"><a href="#rtoc-2">Babelが行っていること</a></li><li class="rtoc-item"><a href="#rtoc-3">仮想DOMとは？</a></li><li class="rtoc-item"><a href="#rtoc-4">まとめ</a></li></ol></div><h2 id="rtoc-1"  class="wp-block-heading">JSXの正体とは？</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="プロ太" class="speech-icon-image"/></figure><div class="speech-name">プロ太</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">おはようございます！今日の授業では、JSXの正体を見ておきましょう！<br>まずは、下記のコードをconsole.logで出力してみると、どうなるか確かめてみましょう！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const sample1 = &lt;h1 className=&quot;greet&quot;&gt;こんにちは！&lt;/h1&gt;;
console.log(sample1);</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="OZ" class="speech-icon-image"/></figure><div class="speech-name">OZ</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">了解です！！入力してみると以下のような結果になりました！！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript" data-line="4-11"><code>const sample1 = &lt;h1 className=&quot;greet&quot;&gt;こんにちは！&lt;/h1&gt;;
console.log(sample1);

// 出力結果
{
  type: &#39;h1&#39;,
  props: {
    className: &#39;greet&#39;,
    children: &#39;こんにちは！&#39;
  }
}</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">あれ？なんか<strong>オブジェクト</strong>が出てきましたね！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうです！実は、<strong><span class="marker-under">JSXは見た目はHTMLっぽく書けますが、内部的にはJavaScriptのオブジェクトに変換されている</span></strong>んです。この<strong><span class="marker-under">変換を行っているのが『Babel』</span></strong>というツールなんです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">へー！じゃあ、Babelは裏で何をしているんですか？</p>
</div></div>



<h2 id="rtoc-2"  class="wp-block-heading">Babelが行っていること</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">実はBabelは、<strong>JSXを<code>React.createElement()</code>という関数の呼び出しに変換</strong>しているんだ。こんな感じです！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>// 元のJSX
const sample1 = &lt;h1 className=&quot;greet&quot;&gt;こんにちは！&lt;/h1&gt;;

// Babelが変換した後のコード
const sample1 = React.createElement(
  &#39;h1&#39;,
  { className: &#39;greet&#39; },
  &#39;こんにちは！&#39;
);

// 実際に生成されるオブジェクト
{
  type: &#39;h1&#39;,
  props: {
    className: &#39;greet&#39;,
    children: &#39;こんにちは！&#39;
  }
}</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！でも、これが何の役に立つんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">これには大きく2つのメリットがあります。</p>
</div></div>



<ol class="wp-block-list">
<li><strong>書きやすさ</strong>: HTMLのような文法で書けるので、見た目の構造が分かりやすい</li>



<li><strong>扱いやすさ</strong>: JavaScriptのオブジェクトに変換されることで、Reactが効率的に画面を更新できる</li>
</ol>



<p class="wp-block-paragraph">実際にもう少し複雑な例を見てみましょう！</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>// JSXの例
const sample2 = (
  &lt;div className=&quot;container&quot;&gt;
    &lt;h1 className=&quot;title&quot;&gt;こんにちは！&lt;/h1&gt;
    &lt;p className=&quot;text&quot;&gt;JSXの勉強中です&lt;/p&gt;
  &lt;/div&gt;
);

// Babelによる変換後
const sample2 = React.createElement(
  &#39;div&#39;,
  { className: &#39;container&#39; },
  React.createElement(&#39;h1&#39;, { className: &#39;title&#39; }, &#39;こんにちは！&#39;),
  React.createElement(&#39;p&#39;, { className: &#39;text&#39; }, &#39;JSXの勉強中です&#39;)
);

// 生成される実際のオブジェクト
{
  type: &#39;div&#39;,
  props: {
    className: &#39;container&#39;,
    children: [
      {
        type: &#39;h1&#39;,
        props: {
          className: &#39;title&#39;,
          children: &#39;こんにちは！&#39;
        }
      },
      {
        type: &#39;p&#39;,
        props: {
          className: &#39;text&#39;,
          children: &#39;JSXの勉強中です&#39;
        }
      }
    ]
  }
}</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！ちゃんとオブジェクトに変換されるんですね！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうです！そして、このとき<strong><span class="marker-under">生成されたオブジェクトの構造を『仮想DOM（Virtual DOM）』</span></strong>と呼びます。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><strong><span class="marker-under">仮想DOM？</span></strong>なんですかそれ？</p>
</div></div>



<h2 id="rtoc-3"  class="wp-block-heading">仮想DOMとは？</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">簡単に説明すると、<strong><span class="marker-under">実際のHTML DOMの構造をJavaScriptのオブジェクトとして表現したもの</span></strong>なんです。少し見比べてみましょう！</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>// 実際のHTML DOM
&lt;div class=&quot;container&quot;&gt;
  &lt;h1 class=&quot;title&quot;&gt;こんにちは！&lt;/h1&gt;
  &lt;p class=&quot;text&quot;&gt;JSXの勉強中です&lt;/p&gt;
&lt;/div&gt;

// 仮想DOM（JavaScriptオブジェクト）
{
  type: &#39;div&#39;,
  props: {
    className: &#39;container&#39;,
    children: [
      {
        type: &#39;h1&#39;,
        props: {
          className: &#39;title&#39;,
          children: &#39;こんにちは！&#39;
        }
      },
      {
        type: &#39;p&#39;,
        props: {
          className: &#39;text&#39;,
          children: &#39;JSXの勉強中です&#39;
        }
      }
    ]
  }
}</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">この仮想DOMには大きく2つの利点があります。</p>
</div></div>



<ol class="wp-block-list">
<li><strong>効率的な更新</strong>:
<ul class="wp-block-list">
<li>画面の更新が必要なとき、まず仮想DOM上で変更を確認</li>



<li>実際のDOMとの差分だけを更新することで、パフォーマンスが向上</li>
</ul>
</li>



<li><strong>扱いやすさ</strong>:
<ul class="wp-block-list">
<li>JavaScriptのオブジェクトなので、プログラムで扱いやすい</li>



<li>状態管理やテストが容易になる</li>
</ul>
</li>
</ol>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">よって、処理の流れとしては、、、</p>
</div></div>



<ol class="wp-block-list">
<li>JSXを書く</li>



<li>Babelが<code>React.createElement()</code>に変換</li>



<li><code>React.createElement()</code>が仮想DOMオブジェクトを生成</li>



<li>Reactが仮想DOMと実際のDOMを比較</li>



<li>必要な部分だけ実際のDOMを更新</li>
</ol>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">この仕組みのおかげで、<strong><span class="marker-under">JSXで書いたコードが効率的に画面に反映</span></strong>されるんだ！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">へー！単なるオブジェクトに見えたけど、すごく重要な役割があったんですね！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうなんです！だからこそ<strong><span class="marker-under">JSXの正体を理解することは、Reactの理解を深める上でとても重要</span></strong>なんです。</p>
</div></div>



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



<ol class="wp-block-list">
<li>JSXは見た目はHTMLっぽいけど、実際はJavaScriptオブジェクトに変換される</li>



<li>BabelがJSXを<code>React.createElement()</code>の呼び出しに変換する</li>



<li><code>React.createElement()</code>は仮想DOMのオブジェクトを生成する</li>



<li>仮想DOMにより、Reactは効率的に画面を更新できる</li>



<li>この仕組み全体により、開発者が書きやすく、かつ効率的な実装が実現できている</li>
</ol>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">上記の内容をしっかりと理解して、次の学習につなげていきましょう！</p>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://oz006.com/jsx-babel-virtualdom/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>React入門第５回~Propsでコンポーネントに値を渡そう~</title>
		<link>https://oz006.com/props/</link>
					<comments>https://oz006.com/props/#respond</comments>
		
		<dc:creator><![CDATA[oz]]></dc:creator>
		<pubDate>Sat, 09 Nov 2024 08:16:58 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<guid isPermaLink="false">https://oz006.com/?p=410</guid>

					<description><![CDATA[Contents Propsでコンポーネントに値を渡そう 分割代入で書いてみよう 分割代入を復習しておこう Propsにいろんな種類の値を渡してみよう スプレッド構文でPropsを渡す Propsの重要なポイント：読み取 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="1000" src="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp" alt="" class="wp-image-385" srcset="https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b.webp 1000w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-300x300.webp 300w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-150x150.webp 150w, https://oz006.com/wp-content/uploads/2024/11/DALL·E-2024-11-05-09.27.01-A-vibrant-digital-illustration-representing-the-concept-of-_React_-a-popular-JavaScript-library.-Show-a-computer-screen-with-stylized-React-logo-a-b-768x768.webp 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<div id="rtoc-mokuji-wrapper" class="rtoc-mokuji-content frame2 preset6 animation-fade rtoc_open default" data-id="410" data-theme="Cocoon Child">
			<div id="rtoc-mokuji-title" class=" rtoc_left">
			<button class="rtoc_open_close rtoc_open"></button>
			<span>Contents</span>
			</div><ol class="rtoc-mokuji decimal_ol level-1"><li class="rtoc-item"><a href="#rtoc-1">Propsでコンポーネントに値を渡そう</a></li><li class="rtoc-item"><a href="#rtoc-2">分割代入で書いてみよう</a></li><li class="rtoc-item"><a href="#rtoc-3">分割代入を復習しておこう</a></li><li class="rtoc-item"><a href="#rtoc-4">Propsにいろんな種類の値を渡してみよう</a></li><li class="rtoc-item"><a href="#rtoc-5">スプレッド構文でPropsを渡す</a></li><li class="rtoc-item"><a href="#rtoc-6">Propsの重要なポイント：読み取り専用と一方通行</a></li><li class="rtoc-item"><a href="#rtoc-7">特別なプロパティ：<code>props.children</code>を使いこなそう！</a><ul class="rtoc-mokuji mokuji_ul level-2"><li class="rtoc-item"><a href="#rtoc-8"><code>props</code>について</a></li><li class="rtoc-item"><a href="#rtoc-9"><code>props.children</code>について</a></li><li class="rtoc-item"><a href="#rtoc-10"><code>props</code>と<code>props.children</code>の違いを整理しよう！</a></li></ul></li><li class="rtoc-item"><a href="#rtoc-11">まとめ</a></li></ol></div><h2 id="rtoc-1"  class="wp-block-heading">Propsでコンポーネントに値を渡そう</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="OZ" class="speech-icon-image"/></figure><div class="speech-name">OZ</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">プロ太先生~。今日はR<strong><span class="marker-under">eactのコンポーネントにPropsを使ってデータを渡す方法</span></strong>についての授業ですよね？よろしくお願いします！！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="プロ太" class="speech-icon-image"/></figure><div class="speech-name">プロ太</div></div><div class="speech-balloon">
<p class="wp-block-paragraph">はい、OZくん。<strong><span class="marker-under">Propsはコンポーネントに情報を渡すための仕組み</span></strong>です。これによって、<strong><span class="marker-under">コンポーネントの見た目や動作を柔軟に変更することができる</span></strong>ようになります。まず、こんなコンポーネントがあるとしましょう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-file="ColorComponent.jsx" data-lang="JavaScript"><code>import &quot;./ColorComponent.css&quot;;

const ColorComponent = (props) =&gt; {
  return (
    &lt;div className={`color-box ${props.colorClass}`}&gt;
      &lt;h3&gt;This is a color box&lt;/h3&gt;
    &lt;/div&gt;
  );
};

export default ColorComponent;</code></pre></div>



<p class="wp-block-paragraph">ここでは<strong>Propsの<code>colorClass</code>を使って、divタグのクラス名を動的に変更</strong>しています。これによって、コンポーネントの色を変えることができます。</p>



<p class="wp-block-paragraph">関数の引数として<code>props</code>という変数が受け取られています。<code>props</code>には、ColorComponentを使う側で渡されたデータが格納されます。例えば、<code>colorClass</code>というPropsを渡せば、<code>props.colorClass</code>でその値にアクセスできるようになります。</p>



<p class="wp-block-paragraph">実際にColorComponentを使う側のコードを見てみましょう。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-file="App.jsx" data-lang="JavaScript" data-line="6-8"><code>import ColorComponent from &quot;./ColorComponent&quot;;

const App = () =&gt; {
  return (
    &lt;div&gt;
      &lt;ColorComponent colorClass=&quot;blue&quot; /&gt;
      &lt;ColorComponent colorClass=&quot;red&quot; /&gt;
      &lt;ColorComponent colorClass=&quot;green&quot; /&gt;
    &lt;/div&gt;
  );
};

export default App;</code></pre></div>



<p class="wp-block-paragraph">ここでは、3つのColorComponentを使っています。<br><span class="marker-under">それぞれに<code>colorClass</code>というPropsを渡しています</span>。<br><code>&lt;ColorComponent colorClass="blue" /&gt;</code>の場合、<code>props.colorClass</code>の値が<code>"blue"</code>になります。<br>同様に、<code>"red"</code>と<code>"green"</code>が渡されています。</p>



<p class="wp-block-paragraph">そしてColorComponent.cssには以下のようなスタイルを定義します。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-css" data-file="ColorComponent.css" data-lang="CSS"><code>.color-box {
  padding: 20px;
  border-radius: 8px;
  text-align: center;
}

.color-box.blue {
  background-color: #ADD8E6;
  color: #1E90FF;
}

.color-box.red {
  background-color: #FF6961;
  color: #DC143C;
}

.color-box.green {
  background-color: #90EE90;
  color: #006400;
}</code></pre></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="475" src="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-07-1.05.03.png" alt="" class="wp-image-411" srcset="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-07-1.05.03.png 1000w, https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-07-1.05.03-300x143.png 300w, https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-07-1.05.03-768x365.png 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！Propsでクラス名を動的に渡せると、デザインが自由に変えられるんですね。</p>
</div></div>



<h2 id="rtoc-2"  class="wp-block-heading">分割代入で書いてみよう</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そしてさらに、<strong><span class="marker-under">JavaScriptの「分割代入」という機能を使うと、もっと簡単に書けます</span></strong>。例えば、<strong>今は<code>(props)</code>と書いていますが、これを<code>({ colorClass })</code>と書き換えることができます</strong>。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript" data-line="1"><code>const ColorComponent = ({ colorClass }) =&gt; {
  return (
    &lt;div className={`color-box ${colorClass}`}&gt;
      &lt;h3&gt;This is a color box&lt;/h3&gt;
    &lt;/div&gt;
  );
};</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">こうすると、<strong><span class="marker-under"><code>props</code>というオブジェクト全体を受け取る代わりに、必要な<code>colorClass</code>だけを直接受け取ることができるんです</span></strong>。これでコードがすっきりして、何が渡されているのか一目でわかりやすくなりますね！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど、分割代入って便利ですね！じゃあ、<strong><span class="marker-under-red">もし他のPropsも渡したい場合</span></strong>はどうなるんですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">いい質問です。では、<strong><span class="marker-under-red">新しく<code>size</code>というPropsを追加して、色だけでなく大きさも変えたいとしましょう</span></strong>。<code>size</code>には <code>"small"</code> や <code>"large"</code> などの値を渡して、コンポーネントの見た目を調整できますよ。コードを見てみましょう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-file="ColorComponent.jsx" data-lang="JavaScript"><code>import &quot;./ColorComponent.css&quot;;

const ColorComponent = ({ colorClass, size }) =&gt; {
  return (
    &lt;div className={`color-box ${colorClass} ${size}`}&gt;
      &lt;h3&gt;This is a color box&lt;/h3&gt;
    &lt;/div&gt;
  );
};

export default ColorComponent;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">これで、<code>size</code>というPropsも受け取れるようになりました。次に、<code>App</code>コンポーネント側で、<code>ColorComponent</code>に<code>size</code>を渡してみましょう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-file="App.jsx" data-lang="JavaScript" data-line="4-7"><code>import ColorComponent from &quot;./components/Child&quot;;

const App = () =&gt; {
  return (
    &lt;div&gt;
      &lt;ColorComponent colorClass=&quot;blue&quot; size=&quot;small&quot; /&gt;
      &lt;ColorComponent colorClass=&quot;red&quot; size=&quot;large&quot; /&gt;
      &lt;ColorComponent colorClass=&quot;green&quot; size=&quot;small&quot; /&gt;
    &lt;/div&gt;
  );
};

export default App;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">これで、各<code>ColorComponent</code>に対して色だけでなく、大きさも指定できます。CSS側でもサイズに応じたスタイルを追加します。ちなみにCSSは以下のようにしています。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-css" data-file="ColorComponent.css" data-lang="CSS"><code>.color-box {
  padding: 20px;
  border-radius: 8px;
  text-align: center;
}

.color-box.blue {
  background-color: #add8e6;
  color: #1e90ff;
}

.color-box.red {
  background-color: #ff6961;
  color: #dc143c;
}

.color-box.green {
  background-color: #90ee90;
  color: #006400;
}

.color-box.small {
  width: 50%;
  height: 100px;
}

.color-box.large {
  width: 90%;
  height: 200px;
}</code></pre></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="727" src="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-07-8.45.24.png" alt="" class="wp-image-413" srcset="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-07-8.45.24.png 1000w, https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-07-8.45.24-300x218.png 300w, https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-07-8.45.24-768x558.png 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど、Propsを増やしてどんどんカスタマイズできるんですね。これなら、この<code>size</code>や<code>colorClass</code>みたいに、必要な値が増えてきても、すっきりしたコードのままでいられますね。分割代入、便利です。でも、ここで復習しておきたいです！</p>
</div></div>



<h2 id="rtoc-3"  class="wp-block-heading">分割代入を復習しておこう</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうですね。では、ここで少し復習として、<strong><span class="marker-under">分割代入の仕組みについて整理</span></strong>しておきましょう。<strong>分割代入は、オブジェクトや配列の中身を簡単に取り出すための便利な構文</strong>です。ReactのPropsでも使えますが、まずはシンプルな例で見てみましょう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const user = {
  name: &quot;OZ&quot;,
  age: 17,
  club: &quot;badminton&quot;,
};</code></pre></div>



<p class="wp-block-paragraph">この<code>user</code>オブジェクトから<code>name</code>と<code>age</code>だけを取り出したいとき、通常ならこう書きます。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const name = user.name;
const age = user.age;</code></pre></div>



<p class="wp-block-paragraph">これでも取り出せますが、分割代入を使うともっと短く、こんな風に書けます。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const { name, age } = user;</code></pre></div>



<p class="wp-block-paragraph">ここで、<code>const { name, age } = user;</code>と書くと、「userの中から<code>name</code>と<code>age</code>というデータだけを取り出して、個別に変数として使えるようにする」という意味になります。</p>



<p class="wp-block-paragraph"><strong>具体的には、「name」と「age」だけを取り出して、それぞれ別の小箱に入れるような感じ</strong>です。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const name = &quot;OZ&quot;; // userから取り出されたname
const age = 17;    // userから取り出されたage</code></pre></div>



<p class="wp-block-paragraph">では、この分割代入のイメージを使って、Propsでも同じように考えてみましょう。<br>たとえば、先ほどの<code>ColorComponent</code>に渡されるPropsを思い出してください。</p>



<p class="wp-block-paragraph">ColorComponentは、<code>colorClass</code>と<code>size</code>という2つのデータをPropsとして受け取ります。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>&lt;ColorComponent colorClass=&quot;blue&quot; size=&quot;large&quot; /&gt;</code></pre></div>



<p class="wp-block-paragraph">このとき、Reactは<code>ColorComponent</code>に渡されたデータを一つのオブジェクトとしてまとめ、関数の引数<code>props</code>に詰めて渡しています。<code>props</code>はこんな箱のような状態です。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>props
├── colorClass: &quot;blue&quot;
└── size: &quot;large&quot;</code></pre></div>



<p class="wp-block-paragraph">通常なら、この中の<code>colorClass</code>や<code>size</code>にアクセスするために、<code>props.colorClass</code>や<code>props.size</code>と書きます。でも、分割代入を使うと、わざわざ<code>props.</code>と書かなくても、直接値を取り出せるんです！</p>



<p class="wp-block-paragraph"><strong>分割代入を使った書き方</strong></p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const ColorComponent = ({ colorClass, size }) =&gt; {
  return (
    &lt;div className={`color-box ${colorClass} ${size}`}&gt;
      &lt;h3&gt;This is a color box&lt;/h3&gt;
    &lt;/div&gt;
  );
};</code></pre></div>



<p class="wp-block-paragraph">ここで、<code>({ colorClass, size })</code>と書くことで、<code>props</code>という箱から<code>colorClass</code>と<code>size</code>だけを抜き出し、直接使える状態にしています。イメージ的には、Propsからそれぞれのデータを取り出して、別々の小箱に分ける感じです。</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const colorClass = &quot;blue&quot;; // propsから取り出されたcolorClass
const size = &quot;large&quot;;      // propsから取り出されたsize</code></pre></div>



<p class="wp-block-paragraph">こうすることで、<code>props</code>の中身を使うときに<code>props.</code>と書かずに済むので、コードがすっきりして読みやすくなりますね！</p>



<h2 id="rtoc-4"  class="wp-block-heading">Propsにいろんな種類の値を渡してみよう</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">OZくん、さっきの<code>colorClass</code>の例でPropsの使い方は少し理解できたかな？<br>ちなみに、<strong><span class="marker-under">Propsは、文字列だけじゃなくて、数値や関数、ブール値、オブジェクトなど、いろいろな種類の値を渡すことができる</span></strong>んです。実際に以下のような画面を作る具体的なコードで見てみましょう。</p>
</div></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="402" src="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-07-10.17.44.png" alt="" class="wp-image-417" srcset="https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-07-10.17.44.png 1000w, https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-07-10.17.44-300x121.png 300w, https://oz006.com/wp-content/uploads/2024/11/スクリーンショット-2024-11-07-10.17.44-768x309.png 768w" sizes="auto, (max-width: 1000px) 100vw, 1000px" /></figure>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-file="ColorComponent.jsx" data-lang="JavaScript"><code>import &quot;./ColorComponent.css&quot;;

// Propsの分割代入とデフォルト値の設定
const ColorComponent = ({
  colorClass = &quot;green&quot;,       // デフォルトで &quot;green&quot; を設定
  num,
  fn,
  isVisible = false,          // デフォルトで false を設定
  user = { name: &quot;NoName&quot;, age: 0 }, // デフォルトのオブジェクト
}) =&gt; {
  return (
    &lt;div className={`color-box ${colorClass}`}&gt;
      &lt;h3&gt;This is a Color Box&lt;/h3&gt;
      &lt;p&gt;Number: {num}&lt;/p&gt;
      &lt;p&gt;Message: {fn(&quot;こんにちは！&quot;)}&lt;/p&gt;
      &lt;p&gt;Visibility: {isVisible ? &quot;Visible&quot; : &quot;Hidden&quot;}&lt;/p&gt;
      &lt;p&gt;User: {user.name}, Age: {user.age}&lt;/p&gt;
    &lt;/div&gt;
  );
};

export default ColorComponent;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-12 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ02.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">うわ！長いコードになってきましたね。それぞれのPropsの役割を教えてください！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">もちろんです！ここでは<strong><span class="marker-under">Propsを分割代入で受け取り、それぞれにデフォルト値を設定</span></strong>しています。</p>
</div></div>



<ul class="wp-block-list">
<li><strong><code>colorClass</code></strong>：親コンポーネントから渡される色の名前です。<code>colorClass</code>が渡されなければデフォルトで<code>"green"</code>になります。</li>



<li><strong><code>num</code></strong>：数値を受け取るPropsです。ここには数値を直接渡すことができます。</li>



<li><strong><code>fn</code></strong>：関数を受け取るPropsです。親コンポーネントから関数を渡すことで、子コンポーネント内で関数を呼び出せるようになります。</li>



<li><strong><code>isVisible</code></strong>：ブール値を受け取るPropsで、<code>true</code>または<code>false</code>のいずれかになります。デフォルトで<code>false</code>になっていて、渡されればその値を使います。</li>



<li><strong><code>user</code></strong>：オブジェクトを受け取るPropsで、ここでは<code>name</code>と<code>age</code>を持つオブジェクトを想定しています。親からオブジェクトが渡されなければ、<code>{ name: "NoName", age: 0 }</code>というデフォルトのオブジェクトが使われます。</li>
</ul>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！<strong><span class="marker-under">Propsにデフォルト値を設定すると、親からの値がなくてもエラーにならずに使える</span></strong>んですね！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そうなんです。デフォルト値のおかげで、コンポーネントが安定して動作します。<br>例えば、<code>App</code>コンポーネントで以下のようにPropsを渡してみましょう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-file="App.jsx" data-lang="JavaScript"><code>import ColorComponent from &quot;./ColorComponent&quot;;

const App = () =&gt; {
  const greet = (text) =&gt; {
    return `挨拶するね！ ${text}!`;
  };

  return (
    &lt;div&gt;
      &lt;ColorComponent 
        colorClass=&quot;blue&quot; 
        num={123} 
        fn={greet} 
        isVisible={true} 
        user={{ name: &quot;OZ&quot;, age: 17 }} 
      /&gt;
    &lt;/div&gt;
  );
};

export default App;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">このコードだと、Propsが渡されるのは次のような形ですね！</p>



<ul class="wp-block-list">
<li><strong><code>colorClass</code></strong>：<code>"blue"</code></li>



<li><strong><code>num</code></strong>：<code>123</code></li>



<li><strong><code>fn</code></strong>：greet関数</li>



<li><strong><code>isVisible</code></strong>：<code>true</code></li>



<li><strong><code>user</code></strong>：<code>{ name: "OZ", age: 17 }</code></li>
</ul>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">その通りです！これで、<code>ColorComponent</code>内でそれぞれのPropsを使って表示したり、動作させたりできます。デフォルト値も設定してあるので、親から渡されなかった場合でも問題なく動作します。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！理解できました！ただ、渡すpropsの値が多いと少しコードが読みにくい感じはしますよね、、、。</p>
</div></div>



<h2 id="rtoc-5"  class="wp-block-heading">スプレッド構文でPropsを渡す</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">その言葉待っていました！実は<span class="marker-under">スプレッド構文を使うと、オブジェクトの内容を一度に展開してPropsとして渡すことができ</span>、コードを読みやすくできますよ。たとえば、以下のように書けます。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-file="App.jsx" data-lang="JavaScript" data-line="15"><code>import ColorComponent from &quot;./ColorComponent&quot;;

const App = () =&gt; {
  const user = { name: &quot;OZ&quot;, age: 17 };
  const componentProps = {
    colorClass: &quot;blue&quot;,
    num: 123,
    fn: (text) =&gt; `挨拶するね！ ${text}!`,
    isVisible: true,
    user,
  };

  return (
    &lt;div&gt;
      &lt;ColorComponent {...componentProps} /&gt;
    &lt;/div&gt;
  );
};

export default App;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><code>{...componentProps}</code>でPropsをまとめて渡しているんですね！便利！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">その通り！このスプレッド構文を使うことで、Propsが多い場合もコードがすっきりして、まとめて管理しやすくなります。コンポーネントに渡す内容を一箇所にまとめておけるので、修正もしやすくなりますね。</p>
</div></div>



<h2 id="rtoc-6"  class="wp-block-heading">Propsの重要なポイント：読み取り専用と一方通行</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">OZくん、<strong>最後にPropsに関する大事なポイント</strong>を話しておきます。ReactのPropsは「<strong>読み取り専用</strong>」であり、「<strong>親から子へ一方通行</strong>」という特徴を持っています。<br>つまり、<strong><span class="marker-under">Propsとして渡されたデータは子コンポーネントの中で変更することができない</span></strong>んです。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-12 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ02.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">ええ、どういうことですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">じゃあ、例を見てみましょう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const Hello = (props) =&gt; {
  // POINT propsは読み取り専用
  // props.name = &#39;Bob&#39;;
  // エラーが発生！

  return (
    &lt;div&gt;
      &lt;h3&gt;Hello {props.name}&lt;/h3&gt;
    &lt;/div&gt;
  );
};

export default Hello;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">ここでは、<code>props.name</code>に新しい値を代入しようとするとエラーが発生しています。<strong><span class="marker-under">Reactの設計上、Propsの値は変更できないように守られているんです</span></strong>。これはコンポーネント間のデータフローを安定させるための重要なルールなので覚えておきましょう！！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><strong><span class="marker-under">Propsは親から渡されるだけで、子から変更することはできない</span></strong>んですね！了解です！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">これによって、<strong><span class="marker-under">コンポーネントの役割が明確になって、予期しないデータの変更が防止できる</span></strong>んです。これはReactの「<strong>一方向データフロー</strong>」の考え方といって、データの流れが親から子にだけ伝わる仕組みになっているんです。</p>
</div></div>



<h2 id="rtoc-7"  class="wp-block-heading">特別なプロパティ：<code>props.children</code>を使いこなそう！</h2>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">最後に、<code>props.children</code>について説明しますね。もう少しです！頑張ってください！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-12 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ02.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">はい！頑張ります！</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><strong><span class="marker-under"><code>props.children</code>は、特別なプロパティで、コンポーネントの中に他の要素を「挟む」ことで渡せます</span></strong>。たとえば、<code>&lt;Greeting&gt;</code>というコンポーネントを作ったとします。この<code>Greeting</code>の中にメッセージや他の要素を自由に挿入できるようにします。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><strong><span class="marker-under">要素を「挟む」</span></strong>ってどういうことですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">具体例を見てみましょう！まず、以下のように<code>Greeting</code>というコンポーネントを作ります。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript" data-line="5"><code>const Greeting = (props) =&gt; {
  return (
    &lt;div&gt;
      &lt;h2&gt;Welcome!&lt;/h2&gt;
      &lt;div&gt;{props.children}&lt;/div&gt;
    &lt;/div&gt;
  );
};

export default Greeting;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">この<code>Greeting</code>コンポーネントは、<strong><span class="marker-under"><code>props.children</code>というプロパティを使って</span></strong>、呼び出し元から渡された要素を受け取る仕組みになっています。次に、この<code>Greeting</code>を使ってみよう。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript" data-line="5"><code>&lt;Greeting&gt;
  &lt;p&gt;こんにちは！これがGreetingコンポーネントの内部に表示される内容です。&lt;/p&gt;
&lt;/Greeting&gt;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-11 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ03.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph"><code>&lt;Greeting&gt;</code>の中に<code>&lt;p&gt;</code>タグを挟んでいますね。もしかして、こうやって<strong><span class="marker-under">挟むだけで、<code>props.children</code>にその内容が渡される</span></strong>んですか？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">その通り！この場合、<code>props.children</code>には<code><strong>&lt;p&gt;こんにちは！これがGreetingコンポーネントの内部に表示される内容です。&lt;/p&gt;</strong></code>が入ります。この結果、<code>Greeting</code>コンポーネントは以下のようにレンダリングされますよ。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript" data-line="5"><code>&lt;div&gt;
  &lt;h2&gt;Welcome!&lt;/h2&gt;
  &lt;div&gt;
    &lt;p&gt;こんにちは！これがGreetingコンポーネントの内部に表示される内容です。&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど！<code>props.children</code>を使うと、コンポーネントの内容を外から自由に変更できるんですね。便利です！！でも、<strong>普通のpropsとprops.childrenもどっちも何かを受け渡しに使うこと</strong>はわかったんですが、２つの違いがちょっとわかりません、、、。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">いい質問ですね、では、<code>props</code>と<code>props.children</code>にはそれぞれ役割があるから、その違いを整理しておきましょう！！</p>
</div></div>



<h3 id="rtoc-8"  class="wp-block-heading"><code>props</code>について</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">まず、<strong><span class="marker-under"><code>props</code>はコンポーネントに特定の「データ」や「設定」を渡すために</span></strong>使われます。たとえば、<code>Greeting</code>コンポーネントに「名前」を渡したいときは、<code>name</code>という<code>props</code>を設定するんです。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>const Greeting = (props) =&gt; {
  return &lt;h2&gt;Hello, {props.name}!&lt;/h2&gt;;
};</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そして、<code>Greeting</code>を使うときに<code>name</code>プロパティで値を渡します。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>&lt;Greeting name=&quot;OZ&quot; /&gt;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど、<code>props.name</code>を使って「OZ」という名前が渡されるんでしたね！<code>props</code>はこうやって設定を渡す感じでした！分割代入もできましたよね！</p>
</div></div>



<h3 id="rtoc-9"  class="wp-block-heading"><code>props.children</code>について</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">一方で、<code>props.children</code>は「コンポーネントの中に挟む要素」を受け取る特別な<code>props</code>です。たとえば、<code>MessageBox</code>というコンポーネントを作って、その中にメッセージや他の要素を自由に挿入できるようにします。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript" data-line="5"><code>const MessageBox = (props) =&gt; {
  return (
    &lt;div className=&quot;message-box&quot;&gt;
      &lt;h3&gt;メッセージ:&lt;/h3&gt;
      &lt;div&gt;{props.children}&lt;/div&gt;
    &lt;/div&gt;
  );
};</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">そして、<code>MessageBox</code>を使うときに中に要素を挟みます。</p>
</div></div>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>&lt;MessageBox&gt;
  &lt;p&gt;これは重要なお知らせです！&lt;/p&gt;
&lt;/MessageBox&gt;</code></pre></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">この場合、<code>props.children</code>には<code>&lt;p>これは重要なお知らせです！&lt;/p></code>が入るんでしたね！</p>
</div></div>



<h3 id="rtoc-10"  class="wp-block-heading"><code>props</code>と<code>props.children</code>の違いを整理しよう！</h3>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-7 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/OZ01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">なるほど、なんとなく違いが見えてきました！僕なりに、<code>props</code>と<code>props.children</code>の違いをまとめてみますね！！</p>
</div></div>



<ol class="wp-block-list">
<li><strong><code>props</code></strong>: コンポーネントに「設定」や「データ」を渡すためのもの。属性として渡す値を指す。
<ul class="wp-block-list">
<li>例: <code>&lt;Greeting name="OZ" /></code></li>



<li><code>props.name</code>で「OZ」を取得</li>
</ul>
</li>



<li><strong><code>props.children</code></strong>: コンポーネントの「中に挟む要素」を受け取るための特別な<code>props</code>。<code>props.children</code>は、任意のタグや他のコンポーネントをそのまま渡せる</li>
</ol>



<p class="wp-block-paragraph">例）</p>



<div class="hcb_wrap"><pre class="prism off-numbers lang-js" data-lang="JavaScript"><code>&lt;MessageBox&gt;
  &lt;p&gt;これは重要なお知らせです！&lt;/p&gt;
&lt;/MessageBox&gt;</code></pre></div>



<p class="wp-block-paragraph">→<code>props.children</code>で<code>&lt;p>これは重要なお知らせです！&lt;/p></code>を取得</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-8 sbs-stn sbp-l sbis-sb cf block-box not-nested-style cocoon-block-balloon"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://oz006.com/wp-content/uploads/2024/10/プロ太01.png" alt="" class="speech-icon-image"/></figure><div class="speech-name"></div></div><div class="speech-balloon">
<p class="wp-block-paragraph">すばらしいまとめです！！成長しましたね！！先生は嬉しいです。</p>
</div></div>



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



<p class="wp-block-paragraph">Propsを使うと、コンポーネントにさまざまなデータを柔軟に渡し、見た目や動作をカスタマイズできます。分割代入を用いて、必要なデータをすっきりと受け取ることができ、コードの読みやすさも向上します。また、デフォルト値を設定することで、親からのデータがない場合でも安定した動作が可能です。Propsの活用方法を理解し、Reactのコンポーネント設計の幅を広げていきましょう！</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://oz006.com/props/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
