<?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 ‣ てんハロ｜未経験エンジニアのIT学習ログ</title>
	<atom:link href="https://it-bokenki.com/category/react/feed/" rel="self" type="application/rss+xml" />
	<link>https://it-bokenki.com</link>
	<description>Hello Worldから、今日も生きてる</description>
	<lastBuildDate>Fri, 11 Jul 2025 04:54:12 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://it-bokenki.com/wp-content/uploads/2025/06/cropped-ブログ　アイコン-32x32.png</url>
	<title>React ‣ てんハロ｜未経験エンジニアのIT学習ログ</title>
	<link>https://it-bokenki.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Azure Blob Storage にファイルをアップロードする方法【Next.js × React】</title>
		<link>https://it-bokenki.com/2025/06/26/azure-blob/</link>
					<comments>https://it-bokenki.com/2025/06/26/azure-blob/#respond</comments>
		
		<dc:creator><![CDATA[てんハロ運営者]]></dc:creator>
		<pubDate>Thu, 26 Jun 2025 04:07:14 +0000</pubDate>
				<category><![CDATA[API]]></category>
		<category><![CDATA[Next.js]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[クラウド]]></category>
		<category><![CDATA[開発事例]]></category>
		<guid isPermaLink="false">https://it-bokenki.com/?p=3579</guid>

					<description><![CDATA[<p>Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち 全体構成 Azure 側の準備 ファイルを保存する先として Azure Blob Storage を使うために、まずはAzure側での [&#8230;]</p>
<p>The post <a href="https://it-bokenki.com/2025/06/26/azure-blob/">Azure Blob Storage にファイルをアップロードする方法【Next.js × React】</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="てんハロ運営者" class="speech-icon-image"/></figure><div class="speech-name">てんハロ運営者</div></div><div class="speech-balloon">
<p>どもども<br>今回は「Azure Blob Storage にファイルをアップロードする方法」について解説します。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-r sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/5-1-150x150.png" alt="バグヲ" class="speech-icon-image"/></figure><div class="speech-name">バグヲ</div></div><div class="speech-balloon">
<p>Azureって最近よく使われてるやつだよね？<br>でも、いまだによくわかってない…</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="てんハロ運営者" class="speech-icon-image"/></figure><div class="speech-name">てんハロ運営者</div></div><div class="speech-balloon">
<p>こんなあなたにピッタリな記事&#x1f447;</p>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li>Azure側の設定がわからない</li>



<li>APIはどのように記載するの？</li>



<li>とりあえず実装だけ知りたい！</li>
</ul>



<p>がまぁまぁわかります！</p>
</div></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="text-align: center;"><a rel="nofollow" href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NZROH">
<img fetchpriority="high" decoding="async" border="0" width="300" height="250" alt="" src="https://www27.a8.net/svt/bgt?aid=230528653907&#038;wid=001&#038;eno=01&#038;mid=s00000023513004030000&#038;mc=1"></a>
<img decoding="async" border="0" width="1" height="1" src="https://www11.a8.net/0.gif?a8mat=3T911P+F006GI+51FE+NZROH" alt=""></div>



<p class="has-text-align-center"><a href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NWRNM">Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち</a></p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-default">
<a href="https://it-bokenki.com/2025/06/24/npm-vs-pnpm-vs-yarn/" title="npm・yarn・pnpmの違いとは？速度や特徴をざっくり比較！" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img decoding="async" width="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-12-1-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-12-1-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-12-1-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-12-1-160x90.png 160w" sizes="(max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">npm・yarn・pnpmの違いとは？速度や特徴をざっくり比較！</div><div class="blogcard-snippet internal-blogcard-snippet">JavaScriptやTypeScriptのプロジェクトでは、依存関係の管理に「パッケージマネージャー」が欠かせません。この記事では、代表的な3つのパッケージマネージャー「npm」「yarn」「pnpm」の違いを比較し、それぞれのメリット・デメリットを表にまとめて解説します。npmはNode.js公式が提供している標準的なツールで、ほとんどのプロジェクトで使われています。対してyarnはMeta（旧Facebook）が開発したもので、npmよりも速くて安定していると評価されています。そして近年注目されているのがpnpmで、圧倒的なインストール速度とディスク効率の良さから、徐々にシェアを伸ばしています。選び方に迷ったときは、プロジェクトの規模や開発チームの方針を基準にするとよいでしょう。たとえば、モノレポ構成や高速なCI/CDを重視する場合はpnpmが向いています。</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://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc1">全体構成</span></h2>



<figure class="wp-block-image aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="784" height="432" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.00.26.png" alt="Azure Blob Storage にファイルをアップロードする方法【Next.js × React】" class="wp-image-3587" style="width:483px;height:auto" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.00.26.png 784w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.00.26-300x165.png 300w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.00.26-768x423.png 768w" sizes="auto, (max-width: 784px) 100vw, 784px" /></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc2">Azure 側の準備</span></h2>



<p>ファイルを保存する先として <code>Azure Blob Storage</code> を使うために、まずはAzure側での初期設定を行いましょう。</p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc3">STEP1：ストレージアカウントを作成</span></h3>



<ol class="wp-block-list">
<li><a class="" href="https://portal.azure.com/">Azureポータル</a> にログイン</li>



<li>左上の「≡」メニューから「<strong>ストレージアカウント</strong>」を選択し、「<strong>＋作成</strong>」をクリック</li>



<li>以下の<span class="bold-red">※</span><span class="red">1</span>ように項目を入力（最低限でOK）</li>



<li>下部の「<strong>確認および作成</strong>」→「<strong>作成</strong>」を押す</li>



<li>デプロイ完了後、「<strong>リソースに移動</strong>」ボタンをクリック</li>
</ol>



<p><span class="bold-red">※</span><span class="red">1</span></p>



<figure class="wp-block-table is-style-regular"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>設定値</th></tr></thead><tbody><tr><td>サブスクリプション</td><td>任意（通常は1つ）</td></tr><tr><td>リソースグループ</td><td>任意（新規作成でもOK）</td></tr><tr><td>ストレージアカウント名</td><td>例：myuploadstorage123（一意な名前）</td></tr><tr><td>リージョン</td><td>お住まいに近い場所（東日本ならJapan East）</td></tr><tr><td>パフォーマンス</td><td>standard</td></tr><tr><td>冗長性</td><td>ローカル冗長ストレージ (LRS)</td></tr></tbody></table></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc4">STEP2：Blobコンテナーを作成</span></h3>



<ol class="wp-block-list">
<li>ストレージアカウントの画面左メニューから「<strong>データストレージ</strong>」→「<strong>コンテナー</strong>」を選択</li>



<li>上部の「＋<strong>コンテナー</strong>」ボタンを押して以下の<span class="bold-red">※</span><span class="red">2</span>ように項目を入力</li>



<li>「<strong>作成</strong>」ボタンを押す</li>
</ol>



<p><span class="bold-red">※</span><span class="red">2</span></p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>設定値</th></tr></thead><tbody><tr><td>名前</td><td>例：upload</td></tr><tr><td>パブリックアクセスレベル</td><td>プライベート（推奨）</td></tr></tbody></table></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc5">STEP3：接続文字列を取得して .env.local に設定</span></h3>



<ol class="wp-block-list">
<li>ストレージアカウントの左メニューをスクロールし、「<strong>セキュリティとネットワーク</strong>」セクションにある「<strong>アクセスキー</strong>」をクリック</li>



<li>「key1」の項目にある「<strong>接続文字列</strong>」をコピー</li>



<li>プロジェクト直下の <code>.env.local</code> ファイルに以下を追加</li>
</ol>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=（コピーした内容）
AZURE_CONTAINER_NAME=（設定した名前）</code></pre></div>



<p><code>.env.local</code> を変更したあとは、<strong>Next.js の開発サーバーを再起動</strong>してください。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc6">ファイルアップロード用UIの作成（React）</span></h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>&#8220;use client&#8221;;
import { useState, useRef } from &#8220;react&#8221;;
export default function DragAndDropUploader() {
  // ドラッグ中かどうかの状態
  const [isDragging, setIsDragging] = useState(false);
  // メッセージ表示用（成功・エラー）
  const [message, setMessage] = useState(&#8220;&#8221;);
  // input要素の参照（隠してボタンから開く用）
  const fileInputRef = useRef&lt;HTMLInputElement>(null);
  // 選択されたファイル一覧
  const [selectedFiles, setSelectedFiles] = useState&lt;File[]>([]);
  // ファイルがドロップされた時の処理
  const handleDrop = (e: React.DragEvent&lt;HTMLDivElement>) => {
    e.preventDefault();
    setIsDragging(false);
    const files = Array.from(e.dataTransfer.files); // FileList → 配列に変換
    if (files.length === 0) return;
    setSelectedFiles(files);
  };
  // ドラッグ中（枠が赤くなる）
  const handleDragOver = (e: React.DragEvent&lt;HTMLDivElement>) => {
    e.preventDefault();
    setIsDragging(true);
  };
  // ドラッグが外れたとき（赤枠を戻す）
  const handleDragLeave = () => setIsDragging(false);
  // ファイル選択時の処理
  const handleFileSelect = (e: React.ChangeEvent&lt;HTMLInputElement>) => {
    const files = Array.from(e.target.files || []);
    if (files.length === 0) return;
    setSelectedFiles(files);
  };
  // 一括取消（ファイルクリア）
  const handleClearFiles = () => {
    setSelectedFiles([]);
    setMessage(&#8220;&#8221;);
  };
  // ボタンクリック → input をクリックさせる
  const handleButtonClick = () => {
    fileInputRef.current?.click();
  };
  // アップロード処理
  const handleUpload = async () => {
    if (selectedFiles.length === 0) {
      setMessage(&#8220;&#x274c; ファイルが選択されていません&#8221;);
      return;
    }
    const formData = new FormData();
    selectedFiles.forEach((file) => formData.append(&#8220;files&#8221;, file));
    try {
      // APIにPOST
      const res = await fetch(&#8220;/api/upload&#8221;, {
        method: &#8220;POST&#8221;,
        body: formData,
      });
      if (res.ok) {
        setMessage(&#8220;&#x2705; アップロード成功しました&#8221;);
      } else {
        const data = await res.json();
        setMessage(&#8220;&#x274c; アップロード失敗: &#8221; + (data.error || res.statusText));
      }
    } catch {
      setMessage(&#8220;&#x274c; アップロード中にエラーが発生しました&#8221;);
    }
  };
  return (
    &lt;div className=&#8221;m-5 mx-auto w-fit&#8221;>
      &lt;h2>&#x1f4e5; スキルシートをアップロード&lt;/h2>
      {/* ドラッグ＆ドロップ枠 */}
      &lt;div
        onDrop={handleDrop}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        className={`w-[620px] h-[320px] border-2 border-dashed rounded p-5 text-center transition-colors duration-300 ${
          isDragging ? &#8220;border-red-500&#8221; : &#8220;border-gray-300&#8221;
        } bg-gray-100 flex items-center justify-center`}
      >
        &lt;div>
          &lt;p>{isDragging ? &#8220;ここにドロップ&#8221; : &#8220;ファイルをドラッグ＆ドロップ&#8221;}&lt;/p>
          &lt;p>または&lt;/p>
          &lt;button
            onClick={handleButtonClick}
            className=&#8221;bg-red-500 text-white px-4 py-2 rounded&#8221;
          >
            ファイルを選択
          &lt;/button>
        &lt;/div>
        {/* ファイル選択用input（非表示） */}
        &lt;input
          type=&#8221;file&#8221;
          multiple
          ref={fileInputRef}
          onChange={handleFileSelect}
          style={{ display: &#8220;none&#8221; }}
        />
      &lt;/div>
      {/* 選択されたファイルの表示 + ✕ボタン */}
      {selectedFiles.length > 0 &amp;&amp; (
        &lt;div className=&#8221;mt-4 text-left&#8221;>
          &lt;div className=&#8221;flex items-start justify-between mb-2&#8243;>
            &lt;p className=&#8221;font-semibold&#8221;>選択中のファイル&lt;/p>
            &lt;button
              onClick={handleClearFiles}
              className=&#8221;font-semibold text-sm text-red-600 hover:underline&#8221;
            >
              一括取消
            &lt;/button>
          &lt;/div>
          &lt;ul>
            {selectedFiles.map((file, index) => (
              &lt;li key={index} className=&#8221;flex items-center justify-between mb-1&#8243;>
                &lt;span>{file.name}&lt;/span>
                &lt;button
                  onClick={() =>
                    setSelectedFiles((prev) =>
                      prev.filter((_, i) => i !== index)
                    )
                  }
                  className=&#8221;text-red-600 font-bold&#8221;
                >
                  ✕
                &lt;/button>
              &lt;/li>
            ))}
          &lt;/ul>
        &lt;/div>
      )}
      {/* アップロードボタン */}
      &lt;div>
        &lt;button
          onClick={handleUpload}
          className=&#8221;bg-green-700 text-white px-4 py-2 rounded mt-5&#8243;
        >
          アップロード
        &lt;/button>
        {message &amp;&amp; &lt;p className=&#8221;mt-2&#8243;>{message}&lt;/p>}
      &lt;/div>
    &lt;/div>
  );
}
</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">use client</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">useState</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">useRef</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">react</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">export</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">default</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DragAndDropUploader</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// ドラッグ中かどうかの状態</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">[</span><span style="color: #D8DEE9">isDragging</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">setIsDragging</span><span style="color: #ECEFF4">]</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">useState</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">false</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// メッセージ表示用（成功・エラー）</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">[</span><span style="color: #D8DEE9">message</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">setMessage</span><span style="color: #ECEFF4">]</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">useState</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// input要素の参照（隠してボタンから開く用）</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fileInputRef</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">useRef</span><span style="color: #ECEFF4">&lt;</span><span style="color: #D8DEE9FF">HTMLInputElement</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">null</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// 選択されたファイル一覧</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">[</span><span style="color: #D8DEE9">selectedFiles</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">setSelectedFiles</span><span style="color: #ECEFF4">]</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">useState</span><span style="color: #ECEFF4">&lt;</span><span style="color: #D8DEE9FF">File[]</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF">([])</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// ファイルがドロップされた時の処理</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">handleDrop</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">e</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> React</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">DragEvent</span><span style="color: #ECEFF4">&lt;</span><span style="color: #D8DEE9FF">HTMLDivElement</span><span style="color: #ECEFF4">&gt;)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">preventDefault</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">setIsDragging</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">false</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">files</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Array</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">from</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">dataTransfer</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">files</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// FileList → 配列に変換</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">files</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">length </span><span style="color: #81A1C1">===</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">return;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">setSelectedFiles</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">files</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// ドラッグ中（枠が赤くなる）</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">handleDragOver</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">e</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> React</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">DragEvent</span><span style="color: #ECEFF4">&lt;</span><span style="color: #D8DEE9FF">HTMLDivElement</span><span style="color: #ECEFF4">&gt;)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">preventDefault</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">setIsDragging</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// ドラッグが外れたとき（赤枠を戻す）</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">handleDragLeave</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">setIsDragging</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">false</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// ファイル選択時の処理</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">handleFileSelect</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">e</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> React</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">ChangeEvent</span><span style="color: #ECEFF4">&lt;</span><span style="color: #D8DEE9FF">HTMLInputElement</span><span style="color: #ECEFF4">&gt;)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">files</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Array</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">from</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">target</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">files</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">||</span><span style="color: #D8DEE9FF"> [])</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">files</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">length </span><span style="color: #81A1C1">===</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">return;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">setSelectedFiles</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">files</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// 一括取消（ファイルクリア）</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">handleClearFiles</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">setSelectedFiles</span><span style="color: #D8DEE9FF">([])</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">setMessage</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// ボタンクリック → input をクリックさせる</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">handleButtonClick</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">fileInputRef</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">current</span><span style="color: #ECEFF4">?.</span><span style="color: #88C0D0">click</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// アップロード処理</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">handleUpload</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">selectedFiles</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">length </span><span style="color: #81A1C1">===</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">setMessage</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">&#x274c; ファイルが選択されていません</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">return;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">formData</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">FormData</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">selectedFiles</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">forEach</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">file</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">formData</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">append</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">files</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">file</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">try</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">      </span><span style="color: #616E88">// APIにPOST</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">res</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">fetch</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">/api/upload</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">method</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">POST</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">body</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">formData</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">res</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ok</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">setMessage</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">&#x2705; アップロード成功しました</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">res</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">json</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">setMessage</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">&#x274c; アップロード失敗: </span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">data</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">||</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">res</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">statusText</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">catch</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">setMessage</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">&#x274c; アップロード中にエラーが発生しました</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> (</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;div</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">className</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">m-5 mx-auto w-fit</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;h2&gt;</span><span style="color: #D8DEE9FF">&#x1f4e5; スキルシートをアップロード</span><span style="color: #81A1C1">&lt;/h2&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* ドラッグ＆ドロップ枠 */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;div</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">onDrop</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">handleDrop</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">onDragOver</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">handleDragOver</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">onDragLeave</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">handleDragLeave</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">className</span><span style="color: #81A1C1">={</span><span style="color: #ECEFF4">`</span><span style="color: #A3BE8C">w-[620px] h-[320px] border-2 border-dashed rounded p-5 text-center transition-colors duration-300 </span><span style="color: #81A1C1">${</span></span>
<span class="line"><span style="color: #A3BE8C">          </span><span style="color: #D8DEE9">isDragging</span><span style="color: #A3BE8C"> </span><span style="color: #81A1C1">?</span><span style="color: #A3BE8C"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">border-red-500</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C"> </span><span style="color: #81A1C1">:</span><span style="color: #A3BE8C"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">border-gray-300</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #A3BE8C">        </span><span style="color: #81A1C1">}</span><span style="color: #A3BE8C"> bg-gray-100 flex items-center justify-center</span><span style="color: #ECEFF4">`</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;div&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;p&gt;{</span><span style="color: #D8DEE9">isDragging</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">?</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ここにドロップ</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ファイルをドラッグ＆ドロップ</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">}&lt;/p&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;p&gt;</span><span style="color: #D8DEE9FF">または</span><span style="color: #81A1C1">&lt;/p&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;button</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #8FBCBB">onClick</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">handleButtonClick</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #8FBCBB">className</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">bg-red-500 text-white px-4 py-2 rounded</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            ファイルを選択</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;/button&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;/div&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* ファイル選択用input（非表示） */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;input</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #8FBCBB">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">file</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #8FBCBB">multiple</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #8FBCBB">ref</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">fileInputRef</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #8FBCBB">onChange</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">handleFileSelect</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #8FBCBB">style</span><span style="color: #81A1C1">={</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">display</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">none</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;/div&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* 選択されたファイルの表示 + ✕ボタン */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">{</span><span style="color: #D8DEE9">selectedFiles</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">length </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;&amp;</span><span style="color: #D8DEE9FF"> (</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;div</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">className</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">mt-4 text-left</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;div</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">className</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">flex items-start justify-between mb-2</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;p</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">className</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">font-semibold</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF">選択中のファイル</span><span style="color: #81A1C1">&lt;/p&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;button</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #8FBCBB">onClick</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">handleClearFiles</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #8FBCBB">className</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">font-semibold text-sm text-red-600 hover:underline</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">              一括取消</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;/button&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;/div&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;ul&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">{</span><span style="color: #D8DEE9">selectedFiles</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">map</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">file</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">index</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> (</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">&lt;li</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">key</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">index</span><span style="color: #81A1C1">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">className</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">flex items-center justify-between mb-1</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #81A1C1">&lt;span&gt;{</span><span style="color: #D8DEE9">file</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">name</span><span style="color: #81A1C1">}&lt;/span&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #81A1C1">&lt;button</span></span>
<span class="line"><span style="color: #D8DEE9FF">                  </span><span style="color: #8FBCBB">onClick</span><span style="color: #81A1C1">={</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    </span><span style="color: #88C0D0">setSelectedFiles</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">prev</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                      </span><span style="color: #D8DEE9">prev</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">filter</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">_</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">!==</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">index</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    )</span></span>
<span class="line"><span style="color: #D8DEE9FF">                  </span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">                  </span><span style="color: #8FBCBB">className</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">text-red-600 font-bold</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                  ✕</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #81A1C1">&lt;/button&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">&lt;/li&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            ))</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;/ul&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;/div&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      )</span><span style="color: #81A1C1">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* アップロードボタン */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;div&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;button</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #8FBCBB">onClick</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">handleUpload</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #8FBCBB">className</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">bg-green-700 text-white px-4 py-2 rounded mt-5</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          アップロード</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;/button&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">{</span><span style="color: #D8DEE9">message</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;p</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">className</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">mt-2</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;{</span><span style="color: #D8DEE9">message</span><span style="color: #81A1C1">}&lt;/p&gt;}</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;/div&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;/div&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  )</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc7">ファイルアップロードAPIの作成（Next.js × Azure SDK）</span></h2>



<p><span class="badge-grey">仕様</span><br>ファイル名が一意になるように、アップロードされたファイル名の末尾に<br>「<strong>_YYYYMMDD_hhmm</strong>」と日時を付与してから<code>Azure Blob Storage</code> にアップロードする</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>import { NextResponse } from &#8220;next/server&#8221;;
import { BlobServiceClient } from &#8220;@azure/storage-blob&#8221;;
// POSTメソッドで呼び出されたときの処理
export async function POST(req: Request) {
  try {
    // フロントから送られてきたファイル付きのデータ（FormData）を受け取る
    const formData = await req.formData();
    // name=&#8221;files&#8221; という名前で送られてきたファイル全部取得
    const files = formData.getAll(&#8220;files&#8221;) as File[];
    // ファイルが1つもなかったらエラーを返す
    if (!files.length) {
      return NextResponse.json(
        { error: &#8220;ファイルがありません&#8221; },
        { status: 400 }
      );
    }
    // Azure Storage に接続するためのクライアントを作成
    const blobService = BlobServiceClient.fromConnectionString(
      process.env.AZURE_STORAGE_CONNECTION_STRING! // .env.local に設定した接続文字列
    );
    // コンテナー（事前に作成済み）に接続
    const container = blobService.getContainerClient(
      process.env.AZURE_CONTAINER_NAME!
    );
    // ファイルごとに繰り返す
    for (const file of files) {
      // タイムスタンプを付けて、ファイル名の重複を防ぐ
      const now = new Date();
      const timestamp = `${now.getFullYear()}${String(
        now.getMonth() + 1
      ).padStart(2, &#8220;0&#8221;)}${String(now.getDate()).padStart(2, &#8220;0&#8221;)}_${String(
        now.getHours()
      ).padStart(2, &#8220;0&#8221;)}${String(now.getMinutes()).padStart(2, &#8220;0&#8221;)}`;
      // 元のファイル名と拡張子を分離
      const originalName = file.name;
      const ext = originalName.includes(&#8220;.&#8221;)
        ? &#8220;.&#8221; + originalName.split(&#8220;.&#8221;).pop()
        : &#8220;&#8221;;
      const base = originalName.replace(ext, &#8220;&#8221;);
      // 一意なファイル名を作成（例：resume_20250626_1030.pdf）
      const uniqueName = `${base}_${timestamp}${ext}`;
      // Fileオブジェクト → ArrayBuffer に変換
      const arrayBuffer = await file.arrayBuffer();
      // ArrayBuffer → Node.js の Buffer に変換（Azure用）
      const buffer = Buffer.from(arrayBuffer);
      // Azure上の「保存先ファイル（Blob）」を指定
      const blockBlob = container.getBlockBlobClient(uniqueName);
      // ファイルをアップロード（bufferとして保存）
      await blockBlob.uploadData(buffer);
    }
    // 成功レスポンスを返す
    return NextResponse.json({
      message: &#8220;すべてのファイルをアップロードしました&#8221;,
    });
  } catch (error) {
    // エラーが起きた場合はログを出してエラーを返す
    console.error(&#8220;アップロードエラー:&#8221;, error);
    return NextResponse.json({ error: &#8220;アップロード失敗&#8221; }, { status: 500 });
  }
}
</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">NextResponse</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">next/server</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">BlobServiceClient</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">@azure/storage-blob</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// POSTメソッドで呼び出されたときの処理</span></span>
<span class="line"><span style="color: #81A1C1">export</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">POST</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">req</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> Request</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">try</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// フロントから送られてきたファイル付きのデータ（FormData）を受け取る</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">formData</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">req</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">formData</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// name=&quot;files&quot; という名前で送られてきたファイル全部取得</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">files</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">formData</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">getAll</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">files</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">as</span><span style="color: #D8DEE9FF"> File[]</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// ファイルが1つもなかったらエラーを返す</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #D8DEE9">files</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">length) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NextResponse</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">json</span><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">error</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ファイルがありません</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">status</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">400</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">      )</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Azure Storage に接続するためのクライアントを作成</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">blobService</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">BlobServiceClient</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">fromConnectionString</span><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #D8DEE9">process</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">env</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">AZURE_STORAGE_CONNECTION_STRING</span><span style="color: #81A1C1">!</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// .env.local に設定した接続文字列</span></span>
<span class="line"><span style="color: #D8DEE9FF">    )</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// コンテナー（事前に作成済み）に接続</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">container</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">blobService</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">getContainerClient</span><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #D8DEE9">process</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">env</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">AZURE_CONTAINER_NAME</span><span style="color: #81A1C1">!</span></span>
<span class="line"><span style="color: #D8DEE9FF">    )</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// ファイルごとに繰り返す</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">file</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">of</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">files</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">      </span><span style="color: #616E88">// タイムスタンプを付けて、ファイル名の重複を防ぐ</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">now</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">new</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">Date</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">timestamp</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">`</span><span style="color: #81A1C1">${</span><span style="color: #D8DEE9">now</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">getFullYear</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">}${</span><span style="color: #88C0D0">String</span><span style="color: #ECEFF4">(</span></span>
<span class="line"><span style="color: #A3BE8C">        </span><span style="color: #D8DEE9">now</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">getMonth</span><span style="color: #ECEFF4">()</span><span style="color: #A3BE8C"> </span><span style="color: #81A1C1">+</span><span style="color: #A3BE8C"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #A3BE8C">      </span><span style="color: #ECEFF4">).</span><span style="color: #88C0D0">padStart</span><span style="color: #ECEFF4">(</span><span style="color: #B48EAD">2</span><span style="color: #ECEFF4">,</span><span style="color: #A3BE8C"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">0</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">}${</span><span style="color: #88C0D0">String</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">now</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">getDate</span><span style="color: #ECEFF4">()).</span><span style="color: #88C0D0">padStart</span><span style="color: #ECEFF4">(</span><span style="color: #B48EAD">2</span><span style="color: #ECEFF4">,</span><span style="color: #A3BE8C"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">0</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">}</span><span style="color: #A3BE8C">_</span><span style="color: #81A1C1">${</span><span style="color: #88C0D0">String</span><span style="color: #ECEFF4">(</span></span>
<span class="line"><span style="color: #A3BE8C">        </span><span style="color: #D8DEE9">now</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">getHours</span><span style="color: #ECEFF4">()</span></span>
<span class="line"><span style="color: #A3BE8C">      </span><span style="color: #ECEFF4">).</span><span style="color: #88C0D0">padStart</span><span style="color: #ECEFF4">(</span><span style="color: #B48EAD">2</span><span style="color: #ECEFF4">,</span><span style="color: #A3BE8C"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">0</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">}${</span><span style="color: #88C0D0">String</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">now</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">getMinutes</span><span style="color: #ECEFF4">()).</span><span style="color: #88C0D0">padStart</span><span style="color: #ECEFF4">(</span><span style="color: #B48EAD">2</span><span style="color: #ECEFF4">,</span><span style="color: #A3BE8C"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">0</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">}</span><span style="color: #ECEFF4">`</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">      </span><span style="color: #616E88">// 元のファイル名と拡張子を分離</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">originalName</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">file</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">name</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ext</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">originalName</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">includes</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">?</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">originalName</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">split</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">pop</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">base</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">originalName</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">replace</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">ext</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">      </span><span style="color: #616E88">// 一意なファイル名を作成（例：resume_20250626_1030.pdf）</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">uniqueName</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">`</span><span style="color: #81A1C1">${</span><span style="color: #D8DEE9">base</span><span style="color: #81A1C1">}</span><span style="color: #A3BE8C">_</span><span style="color: #81A1C1">${</span><span style="color: #D8DEE9">timestamp</span><span style="color: #81A1C1">}${</span><span style="color: #D8DEE9">ext</span><span style="color: #81A1C1">}</span><span style="color: #ECEFF4">`</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">      </span><span style="color: #616E88">// Fileオブジェクト → ArrayBuffer に変換</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">arrayBuffer</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">file</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">arrayBuffer</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">      </span><span style="color: #616E88">// ArrayBuffer → Node.js の Buffer に変換（Azure用）</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">buffer</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Buffer</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">from</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">arrayBuffer</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">      </span><span style="color: #616E88">// Azure上の「保存先ファイル（Blob）」を指定</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">blockBlob</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">container</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">getBlockBlobClient</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">uniqueName</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">      </span><span style="color: #616E88">// ファイルをアップロード（bufferとして保存）</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">blockBlob</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">uploadData</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">buffer</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// 成功レスポンスを返す</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NextResponse</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">json</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">message</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">すべてのファイルをアップロードしました</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">catch</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">error</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// エラーが起きた場合はログを出してエラーを返す</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">error</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">アップロードエラー:</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">error</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NextResponse</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">json</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">error</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">アップロード失敗</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">},</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">status</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">500</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"></span></code></pre></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc8">実行画面</span></h2>



<p><code>Azure Blob Storage</code> にまだファイルがアップロードされていない状態</p>



<figure class="wp-block-image size-large has-custom-border"><img loading="lazy" decoding="async" width="1024" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.02-1024x180.png" alt="Azure Blob Storage にファイルをアップロードする方法【Next.js × React】" class="wp-image-3597" style="border-width:1px" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.02-1024x180.png 1024w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.02-300x53.png 300w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.02-768x135.png 768w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.02-1536x270.png 1536w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.02-2048x360.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<p>アップロード画面</p>



<figure class="wp-block-image size-large has-custom-border"><img loading="lazy" decoding="async" width="1024" height="591" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.03.37-1024x591.png" alt="Azure Blob Storage にファイルをアップロードする方法【Next.js × React】" class="wp-image-3592" style="border-width:1px" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.03.37-1024x591.png 1024w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.03.37-300x173.png 300w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.03.37-768x443.png 768w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.03.37-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.03.37.png 1490w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<p>ファイルをアップロードすると、選択中のファイルが表示される</p>



<figure class="wp-block-image size-large has-custom-border"><img loading="lazy" decoding="async" width="1024" height="694" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.35-1024x694.png" alt="Azure Blob Storage にファイルをアップロードする方法【Next.js × React】" class="wp-image-3598" style="border-width:1px" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.35-1024x694.png 1024w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.35-300x203.png 300w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.35-768x521.png 768w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.35.png 1496w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<p>アップロードボタンを押下すると、アップロード完了</p>



<figure class="wp-block-image size-large has-custom-border"><img loading="lazy" decoding="async" width="1024" height="737" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.50-1024x737.png" alt="Azure Blob Storage にファイルをアップロードする方法【Next.js × React】" class="wp-image-3599" style="border-width:1px" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.50-1024x737.png 1024w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.50-300x216.png 300w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.50-768x552.png 768w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.15.50.png 1518w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<p><code>Azure Blob Storage</code> にファイルが格納されていることを確認</p>



<figure class="wp-block-image size-large has-custom-border"><img loading="lazy" decoding="async" width="1024" height="145" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.16.21-1024x145.png" alt="Azure Blob Storage にファイルをアップロードする方法【Next.js × React】" class="wp-image-3600" style="border-width:1px" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.16.21-1024x145.png 1024w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.16.21-300x42.png 300w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.16.21-768x108.png 768w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.16.21-1536x217.png 1536w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-26-11.16.21-2048x289.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="てんハロ運営者" class="speech-icon-image"/></figure><div class="speech-name">てんハロ運営者</div></div><div class="speech-balloon">
<p>おつかれさまでした！</p>
</div></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-default">
<a href="https://it-bokenki.com/2025/06/24/dom-vs-virtual-dom/" title="DOMと仮想DOMの違いをわかりやすく比較！" 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="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-13-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-13-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-13-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-13-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">DOMと仮想DOMの違いをわかりやすく比較！</div><div class="blogcard-snippet internal-blogcard-snippet">DOMと仮想DOMの違いを、お弁当のたとえや図を使ってやさしく解説！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://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:0px" aria-hidden="true" class="wp-block-spacer"></div><p>The post <a href="https://it-bokenki.com/2025/06/26/azure-blob/">Azure Blob Storage にファイルをアップロードする方法【Next.js × React】</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://it-bokenki.com/2025/06/26/azure-blob/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>axiosとは？初心者でもわかる使い方・fetchとの違いを解説</title>
		<link>https://it-bokenki.com/2025/06/16/axios/</link>
					<comments>https://it-bokenki.com/2025/06/16/axios/#respond</comments>
		
		<dc:creator><![CDATA[てんハロ運営者]]></dc:creator>
		<pubDate>Mon, 16 Jun 2025 07:10:02 +0000</pubDate>
				<category><![CDATA[API]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[フロントエンド]]></category>
		<category><![CDATA[axios]]></category>
		<guid isPermaLink="false">https://it-bokenki.com/?p=3463</guid>

					<description><![CDATA[<p>Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち axiosとは？ axios は、JavaScriptでAPI通信（サーバーとのやり取り）を簡単に行うための外部ライブラリです。 シン [&#8230;]</p>
<p>The post <a href="https://it-bokenki.com/2025/06/16/axios/">axiosとは？初心者でもわかる使い方・fetchとの違いを解説</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="てんハロ運営者" class="speech-icon-image"/></figure><div class="speech-name">てんハロ運営者</div></div><div class="speech-balloon">
<p>どもども<br>今回は「axios（アクシオス）」について解説します。</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-r sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/5-1-150x150.png" alt="バグヲ" class="speech-icon-image"/></figure><div class="speech-name">バグヲ</div></div><div class="speech-balloon">
<p>API通信っていろいろあって混乱するんだけど、<br>axiosってなにが便利なの？</p>
</div></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="てんハロ運営者" class="speech-icon-image"/></figure><div class="speech-name">てんハロ運営者</div></div><div class="speech-balloon">
<p>こんなあなたにピッタリな記事&#x1f447;</p>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<ul class="wp-block-list">
<li>axiosってなに？</li>



<li>axiosとfetchの違いは？</li>



<li>API通信がよくわからない</li>
</ul>



<p>がまぁまぁわかります！</p>
</div></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="text-align: center;"><a rel="nofollow" href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NZROH">
<img loading="lazy" decoding="async" border="0" width="300" height="250" alt="" src="https://www27.a8.net/svt/bgt?aid=230528653907&#038;wid=001&#038;eno=01&#038;mid=s00000023513004030000&#038;mc=1"></a>
<img loading="lazy" decoding="async" border="0" width="1" height="1" src="https://www11.a8.net/0.gif?a8mat=3T911P+F006GI+51FE+NZROH" alt=""></div>



<p class="has-text-align-center"><a href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NWRNM">Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち</a></p>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-default">
<a href="https://it-bokenki.com/2025/06/16/async-await-promise-basic/" title="async/awaitとPromiseの違いとは？" 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="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-10-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-10-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-10-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-10-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">async/awaitとPromiseの違いとは？</div><div class="blogcard-snippet internal-blogcard-snippet">非同期処理が難しいと感じている方へ。async/await・Promise・try/catch の基本をやさしく解説します。</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://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc1">axiosとは？</span></h2>



<p><strong><code>axios</code></strong> は、JavaScriptでAPI通信（サーバーとのやり取り）を簡単に行うための<strong>外部ライブラリ</strong>です。</p>



<p><strong>シンプルなコードで通信が実現できます。</strong></p>



<p><span class="keyboard-key">例</span>：</p>



<ul class="wp-block-list">
<li>Webページを開いたときにユーザー情報を取得したい</li>



<li>入力フォームからデータをサーバーに送りたい</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc2">axiosは何ができるの？</span></h2>



<p><code>axios</code>を使うと、以下のような操作が簡単にできます。</p>



<ul class="wp-block-list">
<li>GETリクエスト（データを取得）</li>



<li>POSTリクエスト（データを送信）</li>



<li>JSONデータの自動変換</li>



<li>エラー処理（HTTPステータスも catch できる）</li>



<li>タイムアウトやリトライの設定</li>



<li>リクエストヘッダーの共通管理</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc3">axiosとfetchの違いは？</span></h2>



<p>初心者にとって混乱しやすいのがここ。実は、JavaScriptには標準の通信手段として <code>fetch</code> という関数もあります。</p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc4">同じGET処理をaxiosとfetchで書くと？</span></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// fetch版
fetch("https://api.example.com/users")
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

// axios版
import axios from "axios";

axios.get("https://api.example.com/users")
  .then(res => console.log(res.data))
  .catch(err => console.error(err));</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">// fetch版</span></span>
<span class="line"><span style="color: #88C0D0">fetch</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">https://api.example.com/users</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">then</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">res</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">res</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">json</span><span style="color: #D8DEE9FF">())</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">then</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">log</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF">))</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">catch</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">err</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">error</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">err</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// axios版</span></span>
<span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">axios</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">axios</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">axios</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">https://api.example.com/users</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">then</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">res</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">log</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">res</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF">))</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">catch</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">err</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">error</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">err</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><thead><tr><th>比較項目</th><th>fetch</th><th>axios</th></tr></thead><tbody><tr><td>JSON変換</td><td><code>.json()</code> が毎回必要</td><td>自動で変換、<code>res.data</code> ですぐ使える</td></tr><tr><td>エラー処理</td><td>通信エラーしか catch できない</td><td>HTTPエラー（400, 500番台）も catch 可能</td></tr><tr><td>タイムアウト設定</td><td>自力でAbortControllerが必要</td><td><code>timeout</code> オプションですぐ設定可能</td></tr><tr><td>リクエスト共通化</td><td>毎回ヘッダー設定などを記述</td><td><code>axios.defaults</code> で一括設定可能</td></tr><tr><td>2025年の使用状況</td><td>学習・小規模開発に多い</td><td>チーム・実務では今もaxiosが主流</td></tr></tbody></table></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc5">axiosとfetch どっちを使えばいいの？</span></h3>



<p>&#x2705;&#xfe0f; <strong>学習や練習なら fetch でもOK</strong><br>ライブラリ不要で軽い</p>



<p>&#x2705;&#xfe0f; <strong>実務やチーム開発なら axios をおすすめ</strong><br>冗長な処理を減らせて、保守しやすく、失敗しづらい</p>



<p>2025年現在でも、<strong>ReactやVueなどの現場ではaxiosがよく使われています。</strong></p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc6">axiosの使い方</span></h2>



<h3 class="wp-block-heading"><span id="toc7">axiosインストール方法</span></h3>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>npm install axios
# または
yarn add axios</code></pre></div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc8">基本的な使い方（GET/POST）</span></h3>



<p>axiosを使って、サーバーからデータを取得（GET）・送信（POST）する例です。<br><code>res.data</code> でサーバーからのデータにアクセスできます。<br>エラーが起きたときは <code>.catch()</code> で内容を確認できます。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>// GETリクエスト
axios.get(&#8220;/api/user&#8221;)
  .then(res => console.log(res.data))
  .catch(err => console.error(err));
// POSTリクエスト
axios.post(&#8220;/api/user&#8221;, { name: &#8220;太郎&#8221; })
  .then(res => console.log(res.data))
  .catch(err => console.error(err));
</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">// GETリクエスト</span></span>
<span class="line"><span style="color: #D8DEE9">axios</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">/api/user</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">then</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">res</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">log</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">res</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF">))</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">catch</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">err</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">error</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">err</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// POSTリクエスト</span></span>
<span class="line"><span style="color: #D8DEE9">axios</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">post</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">/api/user</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">太郎</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">then</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">res</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">log</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">res</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF">))</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">catch</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">err</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">error</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">err</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



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



<ul class="wp-block-list">
<li>axiosは、JavaScriptでAPI通信を行うための便利なライブラリ</li>



<li>fetchよりも書きやすく、実務で使いやすい工夫がたくさん</li>



<li>初心者はまず「GETでデータ取得 → .then(res.data)」を覚えればOK！</li>
</ul>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="てんハロ運営者" class="speech-icon-image"/></figure><div class="speech-name">てんハロ運営者</div></div><div class="speech-balloon">
<p>おつかれさまでした！</p>
</div></div><p>The post <a href="https://it-bokenki.com/2025/06/16/axios/">axiosとは？初心者でもわかる使い方・fetchとの違いを解説</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://it-bokenki.com/2025/06/16/axios/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>async/awaitとPromiseの違いとは？</title>
		<link>https://it-bokenki.com/2025/06/16/async-await-promise-basic/</link>
					<comments>https://it-bokenki.com/2025/06/16/async-await-promise-basic/#respond</comments>
		
		<dc:creator><![CDATA[てんハロ運営者]]></dc:creator>
		<pubDate>Mon, 16 Jun 2025 06:29:26 +0000</pubDate>
				<category><![CDATA[IT基礎知識]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[フロントエンド]]></category>
		<category><![CDATA[async/await]]></category>
		<category><![CDATA[Promise]]></category>
		<guid isPermaLink="false">https://it-bokenki.com/?p=3430</guid>

					<description><![CDATA[<p>でじぼうです。 この記事では、JavaScriptの中でもつまずきやすい「非同期処理」について、丁寧に解説します。 Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち 非同期処理ってなに [&#8230;]</p>
<p>The post <a href="https://it-bokenki.com/2025/06/16/async-await-promise-basic/">async/awaitとPromiseの違いとは？</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>でじぼうです。</p>



<p>この記事では、JavaScriptの中でもつまずきやすい「非同期処理」について、丁寧に解説します。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="でじぼう" class="speech-icon-image"/></figure><div class="speech-name">でじぼう</div></div><div class="speech-balloon">
<p>この記事は下記の方がおすすめ！</p>



<ul class="wp-block-list">
<li style="font-size:15px">非同期処理ってなに？</li>



<li style="font-size:15px">async/awaitってなに？</li>



<li style="font-size:15px">async/awaitとPromiseの違いとは？</li>
</ul>
</div></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="text-align: center;"><a rel="nofollow" href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NZROH">
<img loading="lazy" decoding="async" border="0" width="300" height="250" alt="" src="https://www27.a8.net/svt/bgt?aid=230528653907&#038;wid=001&#038;eno=01&#038;mid=s00000023513004030000&#038;mc=1"></a>
<img loading="lazy" decoding="async" border="0" width="1" height="1" src="https://www11.a8.net/0.gif?a8mat=3T911P+F006GI+51FE+NZROH" alt=""></div>



<p class="has-text-align-center"><a href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NWRNM">Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち</a></p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-embed is-type-wp-embed is-provider-it wp-block-embed-it"><div class="wp-block-embed__wrapper">
<a href="https://it-bokenki.com/2025/06/16/zod-object-validation/" title="Zodの .object() とセットで使うバリデーション構文まとめ" 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="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-9-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-9-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-9-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-9-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">Zodの .object() とセットで使うバリデーション構文まとめ</div><div class="blogcard-snippet internal-blogcard-snippet">Zodの.object()と組み合わせて使うpartialやsuperRefineなどの構文を、初心者にもわかりやすく解説します。</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://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
</div></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc1">非同期処理ってなに？</span></h2>



<p>「非同期処理」とは、<span class="marker"><strong>時間のかかる処理を待っている間に、他の作業を進められるようにする仕組み</strong></span>です。</p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc2"> 例：サーバーからデータを取得する場合</span></h3>



<p>通常のウェブサイトでは、次のようなことがよくあります</p>



<ol start="1" class="wp-block-list">
<li>サイトを開くときに、サーバーからデータを取りに行く</li>



<li>この取得に数秒かかることもある</li>



<li>もしデータを待っている間に画面が止まっていたら、ユーザー体験が悪くなる</li>
</ol>



<p>そこで使われるのが「<strong><span class="marker">非同期処理</span></strong>」です。</p>



<p>非同期処理にすると、データを待っている間にも他の操作を続けることができます。ユーザーにとってスムーズな体験を実現できるのです。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc3">Promise（プロミス）とは？</span></h2>



<p>あとで<span class="marker"><strong>「結果が返ってくるよ！」と約束してくれる仕組み</strong></span>です。</p>



<p>JavaScriptでは、時間がかかる処理（たとえば fetch や setTimeout）に対して、 「すぐには結果が出ないけど、終わったら結果を返すね！」という <span class="marker"><strong>箱</strong></span> を渡してくれます。</p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc4">Promiseの状態は3つ</span></h3>



<p>Promise は、非同期処理の進行に応じて、下記のいずれかの状態を取ります。</p>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>状態</th></tr></thead><tbody><tr><td><code><code><span class="marker"><strong>pending</strong></span></code>（ペンディング）</code></td><td>&#x23f3; 実行中</td></tr><tr><td><code><code><strong><span class="marker">fulfilled</span></strong></code>（フルフィルド）</code></td><td>&#x2705; 完了</td></tr><tr><td><code><span class="marker"><strong>rejected</strong></span></code>（リジェクテッド）</td><td>&#x274c; エラー</td></tr></tbody></table></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc5">.then() / .catch() の使い方</span></h3>



<p><code>Promise</code> が返される処理には、結果が返ってきたあとにどう処理するかを <code>.then()</code> と <code>.catch()</code> で書くことができます。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>fetch(&#8220;https://example.com&#8221;)
  .then((res) => res.json())
  .then((data) => console.log(data))
  .catch((error) => console.error(&#8220;失敗しました&#8221;, error));
</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">fetch</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">https://example.com</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">then</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">res</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">res</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">json</span><span style="color: #D8DEE9FF">())</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">then</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">data</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">log</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF">))</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">catch</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">error</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">error</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">失敗しました</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">error</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<ul class="wp-block-list">
<li><code>.then()</code> は「成功したらこれをしてね」</li>



<li><code>.catch()</code> は「失敗したらこれをしてね」</li>
</ul>



<p>このように、<strong><span class="marker">Promiseの結果に対して、処理を“つなげて”書ける</span></strong>のが特徴です。</p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc6">なぜ .then() / .catch() が使えるの？</span></h3>



<p>それは、返り値が「Promise型」だからです。</p>



<p>JavaScriptでは、<span class="marker"><code>.then()</code> や <code>.catch()</code> は <strong>Promise型の値にしか使えません</strong></span>。</p>



<p>&#x2705; <code>.then()</code> を使えるのは Promise型 だけです。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const result = fetch(&#8220;https://example.com&#8221;);
console.log(result); // → Promise { &lt;pending> }</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">result</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">fetch</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">https://example.com</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">log</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">result</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// → Promise { &lt;pending&gt; }</span></span></code></pre></div>



<p>&#x274c; Promise を返さない関数に .then() は使えない</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>function greet() {
  return &#8220;こんにちは&#8221;; // ただの文字列
}
greet().then((msg) => console.log(msg)); // &#x274c; エラー！</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">greet</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">こんにちは</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// ただの文字列</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">greet</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">then</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">msg</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">log</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">msg</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// &#x274c; エラー！</span></span></code></pre></div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc7">返り値を見ずに「Promise型かどうか」を見分けるには？</span></h3>



<ol start="1" class="wp-block-list">
<li><strong>関数の仕様を調べる</strong>
<ul class="wp-block-list">
<li>公式ドキュメントや型定義に <code>Promise</code> と書かれていれば、Promise型の返り値です。</li>



<li>例：<code>fetch()</code> や <code>axios.get()</code> は Promise を返すと明記されています。</li>
</ul>
</li>



<li><strong>関数の型アノテーション（TypeScript）</strong>
<ul class="wp-block-list">
<li><code>function getData(): Promise&lt;string&gt; { ... }</code> のように <code>Promise&lt;型&gt;</code> と書かれていれば、明確に Promise型です。</li>
</ul>
</li>



<li><strong>返り値に .then() を使ってみる（最終手段）</strong>
<ul class="wp-block-list">
<li>実際に <code>.then()</code> をつけて動作するか試すと、Promise型かどうかがわかります（ただし危険なので1と2が推奨）</li>
</ul>
</li>
</ol>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image aligncenter"><img decoding="async" src="https://www24.a8.net/svt/bgt?aid=230520456030&amp;wid=001&amp;eno=01&amp;mid=s00000016188001099000&amp;mc=1" alt=""/></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc8">async / await とは？</span></h2>



<p><code>.then()</code> だけだと、処理が長くなると読みづらくなります。 それをもっと“ふつうの順番”っぽく書けるようにしたのが、<code>async</code> と <code>await</code> です。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>async function loadData() {
  const res = await fetch(&#8220;https://example.com&#8221;);
  const data = await res.json();
  console.log(data);
}</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">loadData</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">res</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">fetch</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">https://example.com</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">res</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">json</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">log</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<ul class="wp-block-list">
<li><code>async</code> は「この関数は非同期（Promise）を使うよ」と宣言するもの</li>



<li><code>await</code> は「この処理が終わるまで“ちょっと待って”ね」という意味</li>
</ul>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc9">注意：await は async がついた関数の中でしか使えない</span></h3>



<p><code>await</code> は、「Promiseの結果を待つ」キーワードですが、 それ単体では使えず、<strong><span class="marker">必ず <code>async</code> 関数の中で使う必要がある</span></strong>と覚えておきましょう。</p>



<p>&#x2705; 正しい書き方（async 関数の中で await を使う）</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>async function getData() {
  const result = await fetch(&#8220;https://example.com&#8221;);
  const json = await result.json();
  console.log(json);
}</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">getData</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">result</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">fetch</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">https://example.com</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">json</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">result</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">json</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">log</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">json</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<p> &#x274c; エラーになる例（関数の外で await を使っている）</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const result = await fetch(&#8220;https://example.com&#8221;);</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">result</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">fetch</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">https://example.com</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc10">try { &#8230; } catch { &#8230; } とは？</span></h2>



<p>非同期処理をしていると、失敗することもあります。 たとえば、サーバーが止まっていたり、ネットがつながっていなかったりする状況です。</p>



<p>そんなときに、エラーが出てプログラムが止まらないようにするための仕組みが、 <code>try</code> と <code>catch</code> です。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>async function getData() {
  try {
    const res = await fetch(&#8220;https://example.com&#8221;);
    const data = await res.json();
    console.log(data);
  } catch (err) {
    console.error(&#8220;エラーが起きました:&#8221;, err);
  }
}</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">getData</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">try</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">res</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">fetch</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">https://example.com</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">res</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">json</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">log</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">catch</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">err</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">error</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">エラーが起きました:</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">err</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<ul class="wp-block-list">
<li><code>try</code> の中に「失敗するかもしれない処理」を書く</li>



<li><code>catch</code> の中に「失敗したときにどうするか」を書く</li>
</ul>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image aligncenter"><img decoding="async" src="https://www26.a8.net/svt/bgt?aid=250611125635&amp;wid=001&amp;eno=01&amp;mid=s00000001817008016000&amp;mc=1" alt=""/></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc11">.catch() と try/catch の違いは？</span></h2>



<p>どちらも「エラー処理」ですが、使い方が違います。</p>



<p><code>.then()</code> を使うなら <code>.catch()</code> を、 <code>await</code> を使うなら <code>try/catch</code> を使うのが基本の形です。</p>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>使える場面</th><th>処理の書き方</th></tr></thead><tbody><tr><td><code>.catch()</code></td><td><code>.then()</code> で書く場合</td><td><code>.then().catch()</code></td></tr><tr><td><code>try/catch</code></td><td><code>async/await</code> で書く場合</td><td><code>try { await ... } catch {}</code></td></tr></tbody></table></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc12">async/await・.then()/.catch()・try/catch を全部使った例</span></h2>



<p>下記のコードは、<strong>Reactを使って非同期処理の動作を試すサンプルアプリ</strong>です。<br>簡単にいうと、「ユーザー情報を取得 → その名前を使ってあいさつ文を表示」する処理です。</p>



<p><strong>言語</strong>：JavaScript<br><strong>ライブラリ</strong>：React</p>



<h3 class="wp-block-heading"><span id="toc13">正常終了</span></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>import React, { useEffect, useState } from &#8220;react&#8221;;
function App() {
  const [msg, setMsg] = useState(&#8220;&#8221;);
  useEffect(() => {
    (async () => {
      try {
        const res = await mockFetchUser();
        const data = await res.json();
        someAsyncOperation(data)
          .then(setMsg)
          .catch((e) => setMsg(&#8220;中のエラー: &#8221; + e));
      } catch (e) {
        setMsg(&#8220;fetchのエラー: &#8221; + e);
      }
    })();
  }, []);
  return (
    &lt;div>
      &lt;h1>React 非同期処理テスト&lt;/h1>
      &lt;p>{msg}&lt;/p>
    &lt;/div>
  );
}
const mockFetchUser = () =>
  Promise.resolve({ json: () => Promise.resolve({ name: &#8220;太郎さん&#8221; }) });
const someAsyncOperation = (d) =>
  d.name
    ? Promise.resolve(&#8220;こんにちは、&#8221; + d.name)
    : Promise.reject(&#8220;名前がありません&#8221;);
export default App;
</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">React</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">useEffect</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">useState</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">react</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">App</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">[</span><span style="color: #D8DEE9">msg</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">setMsg</span><span style="color: #ECEFF4">]</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">useState</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">useEffect</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    (</span><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">try</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">res</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">mockFetchUser</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">res</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">json</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">someAsyncOperation</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">then</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">setMsg</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">catch</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">setMsg</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">中のエラー: </span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">catch</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">setMsg</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">fetchのエラー: </span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">e</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">},</span><span style="color: #D8DEE9FF"> [])</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> (</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;div&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;h1&gt;</span><span style="color: #D8DEE9FF">React 非同期処理テスト</span><span style="color: #81A1C1">&lt;/h1&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;p&gt;{</span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">}&lt;/p&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;/div&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  )</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">mockFetchUser</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">Promise</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">resolve</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">json</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Promise</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">resolve</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">太郎さん</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">someAsyncOperation</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">d</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">d</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">name</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">?</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Promise</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">resolve</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">こんにちは、</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">d</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">name</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Promise</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">reject</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">名前がありません</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">export</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">default</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">App</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p>&#x2705; 表示結果<br><code>mockFetchUser</code> 関数 → <code>res.json()</code> → <code>data.name</code> が <code>"太郎さん"</code> のため、<br><code>someAsyncOperation</code> の結果「こんにちは、太郎さん」が画面に表示される</p>



<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img loading="lazy" decoding="async" width="954" height="256" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-16-14.10.10.png" alt="async/awaitとPromiseの違いとは？" class="wp-image-3472" style="border-width:1px;width:533px;height:auto" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-16-14.10.10.png 954w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-16-14.10.10-300x81.png 300w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-16-14.10.10-768x206.png 768w" sizes="auto, (max-width: 954px) 100vw, 954px" /></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc14">.catch() でエラー表示</span></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>// 省略&#8230;
const mockFetchUser = () =>
  Promise.resolve({ json: () => Promise.resolve({ name: &#8220;&#8221; }) });
// 省略&#8230;</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">// 省略...</span></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">mockFetchUser</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">Promise</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">resolve</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">json</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Promise</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">resolve</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #616E88">// 省略...</span></span></code></pre></div>



<p>&#x2705; 表示結果<br><code>mockFetchUser</code> 関数 → <code>res.json()</code> → <code>data.name</code> が <code>undefined</code> または false のため、<br><code>someAsyncOperation</code> は <code>reject("名前がありません")</code> を返し、<br><code>.catch()</code> により「中のエラー: 名前がありません」が画面に表示される。</p>



<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img loading="lazy" decoding="async" width="946" height="258" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-16-14.10.42.png" alt="async/awaitとPromiseの違いとは？" class="wp-image-3474" style="border-width:1px;width:528px;height:auto" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-16-14.10.42.png 946w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-16-14.10.42-300x82.png 300w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-16-14.10.42-768x209.png 768w" sizes="auto, (max-width: 946px) 100vw, 946px" /></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc15">例外発生のため try/catch でエラー表示</span></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>// 省略&#8230;
const mockFetchUser = () => Promise.reject(&#8220;ネットワークエラー&#8221;);
// 省略&#8230;</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">// 省略...</span></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">mockFetchUser</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Promise</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">reject</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ネットワークエラー</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #616E88">// 省略...</span></span></code></pre></div>



<p>&#x2705; 表示結果<br><code>mockFetchUser</code> 関数が <code>reject("ネットワークエラー")</code> を返したため、<br><code>await mockFetchUser()</code> で例外が発生し、<br><code>catch</code> により「fetchのエラー: ネットワークエラー」が画面に表示される。</p>



<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img loading="lazy" decoding="async" width="942" height="220" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-16-14.14.13.png" alt="async/awaitとPromiseの違いとは？" class="wp-image-3477" style="border-width:1px;width:527px;height:auto" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-16-14.14.13.png 942w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-16-14.14.13-300x70.png 300w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-16-14.14.13-768x179.png 768w" sizes="auto, (max-width: 942px) 100vw, 942px" /></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-embed is-type-wp-embed is-provider-it wp-block-embed-it"><div class="wp-block-embed__wrapper">
<a href="https://it-bokenki.com/2025/06/14/status/" title="404？500? ステータスコードとは？よく見るコード厳選まとめ" 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="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-3-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-3-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-3-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-3-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">404？500? ステータスコードとは？よく見るコード厳選まとめ</div><div class="blogcard-snippet internal-blogcard-snippet">開発エンジニアが現場でよく使うHTTPステータスコードを、意味・原因・使われる場面とともにわかりやすく解説！</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://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
</div></figure>



<div style="height:0px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div><p>The post <a href="https://it-bokenki.com/2025/06/16/async-await-promise-basic/">async/awaitとPromiseの違いとは？</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://it-bokenki.com/2025/06/16/async-await-promise-basic/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Zodの .object() とセットで使うバリデーション構文まとめ</title>
		<link>https://it-bokenki.com/2025/06/16/zod-object-validation/</link>
					<comments>https://it-bokenki.com/2025/06/16/zod-object-validation/#respond</comments>
		
		<dc:creator><![CDATA[てんハロ運営者]]></dc:creator>
		<pubDate>Mon, 16 Jun 2025 03:57:31 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[フロントエンド]]></category>
		<category><![CDATA[Zod]]></category>
		<guid isPermaLink="false">https://it-bokenki.com/?p=3373</guid>

					<description><![CDATA[<p>でじぼうです。 Zodを使ったバリデーションで一番よく出てくるのが .object()でも実際の現場では、それだけでは足りないことが多いです。 この記事では .object() と一緒によく使う構文だけにしぼって、未経験 [&#8230;]</p>
<p>The post <a href="https://it-bokenki.com/2025/06/16/zod-object-validation/">Zodの .object() とセットで使うバリデーション構文まとめ</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>でじぼうです。</p>



<p>Zodを使ったバリデーションで一番よく出てくるのが <code>.object()</code><br>でも実際の現場では、それ<strong>だけでは足りないことが多い</strong>です。</p>



<p>この記事では <code>.object()</code> と一緒に<strong>よく使う構文だけ</strong>にしぼって、未経験でもわかるように解説します！</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="でじぼう" class="speech-icon-image"/></figure><div class="speech-name">でじぼう</div></div><div class="speech-balloon">
<p>この記事は下記の方がおすすめ！<br></p>



<ul class="wp-block-list">
<li style="font-size:15px">Zodってなに？</li>



<li style="font-size:15px">.object() ってなに？</li>



<li style="font-size:15px">よく使われる構文の違いが知りたい</li>
</ul>
</div></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="text-align: center;"><a rel="nofollow" href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NZROH">
<img loading="lazy" decoding="async" border="0" width="300" height="250" alt="" src="https://www27.a8.net/svt/bgt?aid=230528653907&#038;wid=001&#038;eno=01&#038;mid=s00000023513004030000&#038;mc=1"></a>
<img loading="lazy" decoding="async" border="0" width="1" height="1" src="https://www11.a8.net/0.gif?a8mat=3T911P+F006GI+51FE+NZROH" alt=""></div>



<p class="has-text-align-center"><a href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NWRNM">Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち</a></p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-default">
<a href="https://it-bokenki.com/2025/06/16/f12-network-tab/" title="【初心者向け】Networkタブの使い方をやさしく解説｜APIの見方や通信トラブル対処まで" 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="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【初心者向け】Networkタブの使い方をやさしく解説｜APIの見方や通信トラブル対処まで</div><div class="blogcard-snippet internal-blogcard-snippet">F12キーで開く「Networkタブ」の基本を初心者向けに解説。通信状況の確認、APIのエラー調査、画面が動かない原因の特定に役立つ見方を紹介します。</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://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc1">Zodとは？</span></h2>



<p>Zodは、TypeScriptで「入力ルール（バリデーション）」を簡単に定義できるライブラリです。</p>



<ul class="wp-block-list">
<li>形式チェック（文字列・数値・メールなど）</li>



<li>必須・任意の設定</li>



<li>条件付きのチェック</li>
</ul>



<p>などが、<strong>読みやすい構文で書ける</strong>のが特徴です。<br>より詳細は下記のブログをご確認ください。</p>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-default">
<a href="https://it-bokenki.com/2025/06/11/zod/" title="Zodとは？React Hook Formとの連携でバリデーション実装" 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="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-1-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-1-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-1-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-1-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">Zodとは？React Hook Formとの連携でバリデーション実装</div><div class="blogcard-snippet internal-blogcard-snippet">TypeScriptで使えるバリデーションライブラリ「Zod」の基本と、React Hook Formとの連携方法を解説します。</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://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc2">.object()とは？</span></h2>



<p>フォーム全体の「入力ルール」をまとめて定義できる、Zodの土台です。</p>



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



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>name</code> は文字列の入力が必要（必須）</li>



<li><code>email</code> はメール形式での入力が必要（必須）</li>
</ul>



<p>このように、<code>.object()</code> を使うことで<strong>複数の入力項目を1つのスキーマとしてまとめる</strong>ことができます。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc3">一緒によく使う構文一覧【目的別】</span></h2>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><thead><tr><th>構文</th><th>できること</th><th>使用頻度</th></tr></thead><tbody><tr><td><code><span class="marker">.superRefine()</span></code></td><td>複数項目をまとめてチェック</td><td>◎ よく使う</td></tr><tr><td><code><span class="marker">.partial()</span></code><br>（パーシャル）</td><td>全ての項目を「入力なしでもOK」に</td><td>◎ よく使う</td></tr><tr><td><code><span class="marker">.merge()</span></code></td><td>スキーマ同士を合体</td><td>○ 時々使う</td></tr><tr><td><code><span class="marker">.extend()</span></code></td><td>既存のスキーマに追加する</td><td>○ 時々使う</td></tr><tr><td><code><span class="marker">.pick()</span></code></td><td>一部の項目だけ取り出す</td><td>○ 時々使う</td></tr><tr><td><code><span class="marker">.omit()</span></code></td><td>一部の項目を除外する</td><td>○ 時々使う</td></tr></tbody></table></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc4">.superRefine()とは？</span></h2>



<p>複数項目を「まとめてチェック」したいときに利用します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const schema = z.object({
  password: z.string(),
  confirm: z.string(),
}).superRefine((data, ctx) => {
  if (data.password !== data.confirm) {
    ctx.addIssue({
      path: [&#8220;confirm&#8221;],
      message: &#8220;パスワードが一致しません&#8221;,
      code: z.ZodIssueCode.custom,
    });
  }
});</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">schema</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">password</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">confirm</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">superRefine</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">data</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ctx</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">data</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">password</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">!==</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">data</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">confirm</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">ctx</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">addIssue</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">path</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> [</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">confirm</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">]</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">message</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">パスワードが一致しません</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">code</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ZodIssueCode</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">custom</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<p>&#x1f4d8; <code>data</code> とは？</p>



<ul class="wp-block-list">
<li><code>z.object({...})</code> に渡したすべての入力値（name, email など）が入っているオブジェクトのことを指す</li>



<li>React Hook Form の <code>getValues()</code> と同じ構造</li>
</ul>



<p>&#x1f4d8; <code>ctx.addIssue()</code> とは？</p>



<ul class="wp-block-list">
<li>条件に合致した場合に、「この項目にエラーがある」と Zod に伝える関数</li>



<li><code>path: ["confirm"]</code> と指定すれば、<code>confirm</code> にエラーメッセージが表示できる</li>



<li><code>code: z.ZodIssueCode.custom</code> は「独自ルールによるエラー」であることを示す<br></li>
</ul>



<p>&#x1f4d8;コード全体の意味</p>



<ul class="wp-block-list">
<li><code>.superRefine()</code> は、バリデーションの<strong>対象全体（objectの中身）にアクセスできる</strong>関数</li>



<li><code>password</code> と <code>confirm</code> が一致していなければ、<code>confirm</code> 項目にエラーを追加</li>
</ul>



<p><span class="badge-yellow">よくある使い方</span></p>



<ul class="wp-block-list">
<li>パスワード確認</li>



<li>日付の前後関係</li>



<li>条件付き入力のバリデーション</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc5">.partial()とは？</span></h2>



<p>全部「任意入力」にするときに利用します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const schema = z.object({
  title: z.string(),
  content: z.string(),
}).partial();</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">schema</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">title</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">content</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">partial</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>title</code> も <code>content</code> も、<strong>未入力でもエラーにならない</strong></li>
</ul>



<p><span class="badge-yellow">よくある使い方</span></p>



<ul class="wp-block-list">
<li>入力フォームで、<strong>どれか1つだけ更新</strong>したいとき（プロフィール編集など）</li>



<li>一部だけ更新するような画面で、<strong>全項目が必須でないとき</strong></li>
</ul>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc6">.optional() でも同じ意味になる</span></h3>



<p>下記の記載は、上記の<code><code>.partial()</code></code>で定義した場合と、結果はまったく同じになります。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const schema = z.object({
  title: z.string().optional(),
  content: z.string().optional(),
});
</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">schema</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">title</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">optional</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">content</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">optional</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc7">では .partial() を使うメリットは？</span></h3>



<ul class="wp-block-list">
<li>プロパティがたくさんあるときに <strong>1つずつ <code>.optional()</code> を書かなくて済む</strong></li>



<li>スキーマを再利用する際に、<strong>必須版と任意版を簡単に切り替えられる</strong></li>
</ul>



<p>&#x2705; <code>.optional()</code> を個別に書いてもOK<br>&#x2705; <code>.partial()</code> は <strong>全部を一括で optional にしたいとき</strong>に便利！</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc8">.merge()とは？</span></h2>



<p>共通ルールと追加ルールを「合体する」ときに利用します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const base = z.object({ id: z.string() });
const detail = z.object({ name: z.string() });

const schema = base.merge(detail);</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">base</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">detail</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">schema</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">base</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">merge</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">detail</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>id</code> と <code>name</code> の両方を含んだ1つのスキーマを作る</li>
</ul>



<p><span class="badge-yellow">よくある使い方</span></p>



<ul class="wp-block-list">
<li>IDだけで定義した共通スキーマに、画面ごとの入力項目（詳細）を足したいとき</li>



<li><strong>共通部分と画面ごとの違いを分けて管理</strong>したいとき（保守性アップ）</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc9">.extend()とは？</span></h2>



<p>既存のスキーマに追加するときに利用します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const user = z.object({ name: z.string() });
const extended = user.extend({ age: z.number() });</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">user</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">extended</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">user</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">extend</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">age</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">number</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>user</code> に <code>age</code> を追加した新しいスキーマを作る</li>
</ul>



<p><span class="badge-yellow">よくある使い方</span></p>



<ul class="wp-block-list">
<li><strong>もとのスキーマを壊さずに</strong>追加したいとき（再利用性アップ）</li>



<li>複数画面で <code>user</code> は共通だが、年齢が必要なのは一部だけ…という場面など</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc10">.pick()とは？</span></h2>



<p>必要な項目だけ「取り出す」ときに利用します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const full = z.object({
  name: z.string(),
  email: z.string(),
  age: z.number(),
});

const nameOnly = full.pick({ name: true });</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">full</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">email</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">age</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">number</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">nameOnly</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">full</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">pick</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>name</code> だけを含むスキーマを作る</li>
</ul>



<p><span class="badge-yellow">よくある使い方</span></p>



<ul class="wp-block-list">
<li>一覧画面などで、<strong>一部の情報だけ使いたいとき</strong></li>



<li>画面に表示するフィールドを限定したいとき</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc11">.omit()とは？</span></h2>



<p>不要な項目だけ「除外する」ときに利用します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const full = z.object({
  name: z.string(),
  email: z.string(),
  age: z.number(),
});

const noEmail = full.omit({ email: true });</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">full</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">email</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">age</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">number</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">noEmail</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">full</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">omit</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">email</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>email</code> を除外したスキーマを作る</li>
</ul>



<p><span class="badge-yellow">よくある使い方</span></p>



<ul class="wp-block-list">
<li>セキュリティ上、<strong>特定の項目を外したいとき</strong>（たとえばパスワードなど）</li>



<li>APIレスポンスで<strong>不要な情報を含めたくないとき</strong></li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc12">補足：.refine() は .object() の中で「項目ごと」に使う</span></h2>



<p><code>.refine()</code> は<strong>単体の項目</strong>に対して使い、複数項目にまたがるときは <code>.superRefine()</code> を使います。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>z.object({
  username: z.string().refine(val => val !== &#8220;admin&#8221;, {
    message: &#8220;admin は使えません&#8221;,
  }),
});</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">username</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">refine</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">val</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">val</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">!==</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">admin</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">message</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">admin は使えません</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>username</code> が &#8220;admin&#8221; だったらエラーになる、という<strong>1つの項目に対する条件</strong></li>
</ul>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-default">
<a href="https://it-bokenki.com/2025/06/16/f12-network-tab/" title="【初心者向け】Networkタブの使い方をやさしく解説｜APIの見方や通信トラブル対処まで" 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="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【初心者向け】Networkタブの使い方をやさしく解説｜APIの見方や通信トラブル対処まで</div><div class="blogcard-snippet internal-blogcard-snippet">F12キーで開く「Networkタブ」の基本を初心者向けに解説。通信状況の確認、APIのエラー調査、画面が動かない原因の特定に役立つ見方を紹介します。</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://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:0px" aria-hidden="true" class="wp-block-spacer"></div><p>The post <a href="https://it-bokenki.com/2025/06/16/zod-object-validation/">Zodの .object() とセットで使うバリデーション構文まとめ</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://it-bokenki.com/2025/06/16/zod-object-validation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>useStateとwatchの違いとは？フォーム入力の管理方法を解説！</title>
		<link>https://it-bokenki.com/2025/06/14/usestate-watch-diff/</link>
					<comments>https://it-bokenki.com/2025/06/14/usestate-watch-diff/#respond</comments>
		
		<dc:creator><![CDATA[てんハロ運営者]]></dc:creator>
		<pubDate>Sat, 14 Jun 2025 03:20:49 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[フロントエンド]]></category>
		<category><![CDATA[React Hook Form]]></category>
		<category><![CDATA[useState]]></category>
		<category><![CDATA[wacth]]></category>
		<guid isPermaLink="false">https://it-bokenki.com/?p=3152</guid>

					<description><![CDATA[<p>でじぼうです。 Reactでフォームを扱うときに、よく登場するのが「useState」と「watch」という言葉。どちらも値の変化を扱うための機能ですが、意味や使い方は少し違います。 Instagramフォロワー数9,5 [&#8230;]</p>
<p>The post <a href="https://it-bokenki.com/2025/06/14/usestate-watch-diff/">useStateとwatchの違いとは？フォーム入力の管理方法を解説！</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>でじぼうです。</p>



<p>Reactでフォームを扱うときに、よく登場するのが「<code>useState</code>」と「<code>watch</code>」という言葉。<br>どちらも<strong>値の変化を扱う</strong>ための機能ですが、意味や使い方は少し違います。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="でじぼう" class="speech-icon-image"/></figure><div class="speech-name">でじぼう</div></div><div class="speech-balloon">
<p>この記事は下記の方がおすすめ！<br></p>



<ul class="wp-block-list">
<li style="font-size:15px">useStateってなに？</li>



<li style="font-size:15px">wacthってなに？</li>



<li style="font-size:15px">useStateとwatchの違いとは？</li>
</ul>
</div></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="text-align: center;"><a rel="nofollow" href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NZROH">
<img loading="lazy" decoding="async" border="0" width="300" height="250" alt="" src="https://www27.a8.net/svt/bgt?aid=230528653907&#038;wid=001&#038;eno=01&#038;mid=s00000023513004030000&#038;mc=1"></a>
<img loading="lazy" decoding="async" border="0" width="1" height="1" src="https://www11.a8.net/0.gif?a8mat=3T911P+F006GI+51FE+NZROH" alt=""></div>



<p class="has-text-align-center"><a href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NWRNM">Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち</a></p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-normal-card">
<a href="https://it-bokenki.com/2025/06/13/devtools/" title="F12で開く開発者ツール（DevTools）の使い方｜初心者でもできるエラー調査と表示確認" 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="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-2-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-2-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-2-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-2-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">F12で開く開発者ツール（DevTools）の使い方｜初心者でもできるエラー調査と表示確認</div><div class="blogcard-snippet internal-blogcard-snippet">F12キーで開く開発者ツール（DevTools）の使い方を初心者向けに解説。HTML/CSSの確認、API通信、エラー調査の基本がまるっとわかります。</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://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc1">useStateについて</span></h2>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc2">useStateとは？</span></h3>



<p>Reactに標準で用意されている <strong>状態を保持・管理するための関数</strong> です。<br>フォームの入力値やボタンのカウントなど、変化する値を保持できます。</p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc3">どんなときに使う？</span></h3>



<ul class="wp-block-list">
<li>入力フォームの値をリアルタイムで表示したいとき</li>



<li>入力に応じて画面の動きを変えたいとき（例：ボタンの活性化・非表示切替など）</li>
</ul>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc4">実際のコード</span></h3>



<div style="height:0px" aria-hidden="true" class="wp-block-spacer"></div>



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

function ProfileForm() {
  const [name, setName] = useState&lt;string>(&#8220;&#8221;);
  const [email, setEmail] = useState&lt;string>(&#8220;&#8221;);
  const [age, setAge] = useState&lt;number | undefined>(undefined);

  return (
    &lt;div>
      &lt;input
        type=&#8221;text&#8221;
        placeholder=&#8221;名前&#8221;
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      &lt;input
        type=&#8221;email&#8221;
        placeholder=&#8221;メールアドレス&#8221;
        value={email}
        onChange={(e) => setEmail(e.target.value)}
      />
      &lt;input
        type=&#8221;number&#8221;
        placeholder=&#8221;年齢&#8221;
        value={age ?? &#8220;&#8221;}
        onChange={(e) => setAge(Number(e.target.value))}
      />

      &lt;p>名前: {name}&lt;/p>
      &lt;p>メール: {email}&lt;/p>
      &lt;p>年齢: {age}&lt;/p>
    &lt;/div>
  );
}

export default ProfileForm;
</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">useState</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">react</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">ProfileForm</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">[</span><span style="color: #D8DEE9">name</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">setName</span><span style="color: #ECEFF4">]</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">useState</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">string</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">[</span><span style="color: #D8DEE9">email</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">setEmail</span><span style="color: #ECEFF4">]</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">useState</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">string</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">[</span><span style="color: #D8DEE9">age</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">setAge</span><span style="color: #ECEFF4">]</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">useState</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">number</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">undefined</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">undefined</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> (</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;div&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;input</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">text</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">placeholder</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">名前</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">value</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">name</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">onChange</span><span style="color: #81A1C1">={</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">setName</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">target</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">value</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;input</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">email</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">placeholder</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">メールアドレス</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">value</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">email</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">onChange</span><span style="color: #81A1C1">={</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">setEmail</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">target</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">value</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;input</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">number</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">placeholder</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">年齢</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">value</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">age</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">??</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">onChange</span><span style="color: #81A1C1">={</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">setAge</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">Number</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">target</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">value</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;p&gt;</span><span style="color: #D8DEE9FF">名前: </span><span style="color: #81A1C1">{</span><span style="color: #D8DEE9">name</span><span style="color: #81A1C1">}&lt;/p&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;p&gt;</span><span style="color: #D8DEE9FF">メール: </span><span style="color: #81A1C1">{</span><span style="color: #D8DEE9">email</span><span style="color: #81A1C1">}&lt;/p&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;p&gt;</span><span style="color: #D8DEE9FF">年齢: </span><span style="color: #81A1C1">{</span><span style="color: #D8DEE9">age</span><span style="color: #81A1C1">}&lt;/p&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;/div&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  )</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">export</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">default</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ProfileForm</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc5">使用上の注意点</span></h3>



<ul class="wp-block-list">
<li>値の更新はすべて自分で <code>onChange</code> を書く必要がある</li>



<li>入力項目が多くなると <code>useState</code> の数も増える</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc6">watchについて</span></h2>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc7">watchとは？</span></h3>



<p><code>watch</code> は、React Hook Form というフォーム管理ライブラリの関数で、<strong>フォームの入力値をリアルタイムで「監視」</strong>できます。<br><br><code>watch</code> は React に標準で含まれているわけではありません。<br>使うには、まず下記コマンドで React Hook Form を別途インストールする必要があります。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>npm install react-hook-form</code></pre></div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc8">どんなときに使う？</span></h3>



<ul class="wp-block-list">
<li>フォームの入力値を簡単に取り出したいとき</li>



<li>複数のフォーム項目をまとめて管理したいとき</li>



<li>バリデーションや送信処理もラクにしたいとき</li>
</ul>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc9">実際のコード</span></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>import { useForm } from &#8220;react-hook-form&#8221;;

type FormData = {
  name: string;
  email: string;
  age: number | undefined;
};

function ProfileForm() {
  const { register, watch } = useForm&lt;FormData>({
    defaultValues: {
      name: &#8220;&#8221;,
      email: &#8220;&#8221;,
      age: undefined,
    },
  });

  const { name, email, age } = watch();

  return (
    &lt;div>
      &lt;input type=&#8221;text&#8221; placeholder=&#8221;名前&#8221; {&#8230;register(&#8220;name&#8221;)} />
      &lt;input type=&#8221;email&#8221; placeholder=&#8221;メールアドレス&#8221; {&#8230;register(&#8220;email&#8221;)} />
      &lt;input type=&#8221;number&#8221; placeholder=&#8221;年齢&#8221; {&#8230;register(&#8220;age&#8221;, { valueAsNumber: true })} />

      &lt;p>名前: {name}&lt;/p>
      &lt;p>メール: {email}&lt;/p>
      &lt;p>年齢: {age}&lt;/p>
    &lt;/div>
  );
}

export default ProfileForm;</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">useForm</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">react-hook-form</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">type</span><span style="color: #D8DEE9FF"> FormData </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  name</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">string;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  email</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">string;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  age</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">number</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">undefined</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">ProfileForm</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">register</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">watch</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">useForm</span><span style="color: #ECEFF4">&lt;</span><span style="color: #D8DEE9FF">FormData</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">defaultValues</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">email</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">age</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">undefined</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">name</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">email</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">age</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">watch</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> (</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;div&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;input</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">text</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">placeholder</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">名前</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">{...</span><span style="color: #88C0D0">register</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">name</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;input</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">email</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">placeholder</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">メールアドレス</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">{...</span><span style="color: #88C0D0">register</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">email</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;input</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">number</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">placeholder</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">年齢</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">{...</span><span style="color: #88C0D0">register</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">age</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">valueAsNumber</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;p&gt;</span><span style="color: #D8DEE9FF">名前: </span><span style="color: #81A1C1">{</span><span style="color: #D8DEE9">name</span><span style="color: #81A1C1">}&lt;/p&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;p&gt;</span><span style="color: #D8DEE9FF">メール: </span><span style="color: #81A1C1">{</span><span style="color: #D8DEE9">email</span><span style="color: #81A1C1">}&lt;/p&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;p&gt;</span><span style="color: #D8DEE9FF">年齢: </span><span style="color: #81A1C1">{</span><span style="color: #D8DEE9">age</span><span style="color: #81A1C1">}&lt;/p&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;/div&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  )</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">export</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">default</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ProfileForm</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc10">使用上の注意点</span></h3>



<ul class="wp-block-list">
<li>React Hook Form の <code>register</code> とのセットが必要</li>



<li>初期値が指定されていないと <code>undefined</code> になることがある</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc11">useState と watch の違い【比較表】</span></h2>



<p>下記に、useState と watch の違いをまとめました。</p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><thead><tr><th>項目</th><th>useState</th><th>watch</th></tr></thead><tbody><tr><td>用途</td><td>値の保存と更新</td><td>入力値のリアルタイム監視</td></tr><tr><td>更新方法</td><td>自分で <span class="marker"><code>onChange</code></span> を書く</td><td>自動で監視される</td></tr><tr><td>導入のしやすさ</td><td>標準のReactで使える</td><td>ライブラリのインストールが必要</td></tr><tr><td>向いている規模</td><td>小規模なフォーム</td><td>項目数が多いフォーム</td></tr><tr><td>型管理（TypeScript）</td><td>一つずつ型を指定</td><td><span class="marker"><code>useForm&lt;FormData&gt;()</code></span>で一括管理</td></tr></tbody></table></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-normal-card">
<a href="https://it-bokenki.com/2025/06/14/status/" title="404？500? ステータスコードとは？よく見るコード厳選まとめ" 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="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-3-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-3-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-3-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-3-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">404？500? ステータスコードとは？よく見るコード厳選まとめ</div><div class="blogcard-snippet internal-blogcard-snippet">開発エンジニアが現場でよく使うHTTPステータスコードを、意味・原因・使われる場面とともにわかりやすく解説！</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://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:0px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc12">結局どっちを使うべき？</span></h2>



<ul class="wp-block-list">
<li><strong>小さいフォーム → <code>useState</code> が手軽</strong></li>



<li>入力項目が多い or バリデーションも管理したい → <code>watch</code>（React Hook Form）がおすすめ</li>
</ul>



<p>React Hook Formを使えば、フォーム管理がスッキリ書けて、バリデーションも簡単に組み込めます。</p><p>The post <a href="https://it-bokenki.com/2025/06/14/usestate-watch-diff/">useStateとwatchの違いとは？フォーム入力の管理方法を解説！</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://it-bokenki.com/2025/06/14/usestate-watch-diff/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MUIとは？ReactでおしゃれなUIがすぐ作れるライブラリを解説！</title>
		<link>https://it-bokenki.com/2025/06/14/mui/</link>
					<comments>https://it-bokenki.com/2025/06/14/mui/#respond</comments>
		
		<dc:creator><![CDATA[てんハロ運営者]]></dc:creator>
		<pubDate>Sat, 14 Jun 2025 05:57:41 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[フロントエンド]]></category>
		<category><![CDATA[MUI]]></category>
		<guid isPermaLink="false">https://it-bokenki.com/?p=3274</guid>

					<description><![CDATA[<p>でじぼうです。 Reactでアプリを作っていると「もっと見た目を整えたい」「CSSがむずかしい」と感じたこと、ありませんか？そんなときに活躍するのが、MUI というライブラリです！ Instagramフォロワー数9,50 [&#8230;]</p>
<p>The post <a href="https://it-bokenki.com/2025/06/14/mui/">MUIとは？ReactでおしゃれなUIがすぐ作れるライブラリを解説！</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>でじぼうです。</p>



<p>Reactでアプリを作っていると「もっと見た目を整えたい」「CSSがむずかしい」と感じたこと、ありませんか？そんなときに活躍するのが、<strong>MUI </strong>というライブラリです！</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="でじぼう" class="speech-icon-image"/></figure><div class="speech-name">でじぼう</div></div><div class="speech-balloon">
<p>この記事は下記の方がおすすめ！<br></p>



<ul class="wp-block-list">
<li style="font-size:15px">MUIとは何か？</li>



<li style="font-size:15px">おしゃれなボタンやフォームをすぐ使いたい</li>



<li style="font-size:15px">ReactでUIを作っているけど、CSSが苦手</li>
</ul>
</div></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="text-align: center;"><a rel="nofollow" href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NZROH">
<img loading="lazy" decoding="async" border="0" width="300" height="250" alt="" src="https://www27.a8.net/svt/bgt?aid=230528653907&#038;wid=001&#038;eno=01&#038;mid=s00000023513004030000&#038;mc=1"></a>
<img loading="lazy" decoding="async" border="0" width="1" height="1" src="https://www11.a8.net/0.gif?a8mat=3T911P+F006GI+51FE+NZROH" alt=""></div>



<p class="has-text-align-center"><a href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NWRNM">Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち</a></p>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-normal-card">
<a href="https://it-bokenki.com/2025/06/14/usestate-watch-diff/" title="useStateとwatchの違いとは？フォーム入力の管理方法を解説！" 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="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-4-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-4-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-4-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-4-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">useStateとwatchの違いとは？フォーム入力の管理方法を解説！</div><div class="blogcard-snippet internal-blogcard-snippet">ReactのuseStateとwatchの違いを初心者向けに解説！フォーム入力の管理方法と使い分けを具体例で紹介します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc1">MUIとは？</span></h2>



<p><strong>MUI</strong>とは<strong>React専用のUIライブラリ</strong>です。<br><br>かんたんに言うと、Reactで使える「見た目が整ったパーツ（部品）」を集めたツール集です。<br><br><span class="badge">例</span></p>



<ul class="wp-block-list">
<li>ボタン</li>



<li>入力欄</li>



<li>ダイアログ（ポップアップ）</li>



<li>ナビゲーションバー</li>
</ul>



<p>などが、すでに整った見た目で提供されており、<strong>自分でCSSを書かなくてもキレイな画面が作れる</strong>のが特徴です。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc2">MUIのインストール方法</span></h2>



<p>MUIを利用するためには、UIコンポーネントライブラリをインストールしなければいけません。<br>以下のコマンドを実行します。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>npm install @mui/material @emotion/react @emotion/styled</code></pre></div>



<p><code>@mui/material</code>：見た目の部品である、<strong>UIコンポーネントを提供</strong>するライブラリ</p>



<p><code>@emotion/react</code>：部品に<strong>スタイルを反映させる</strong>ライブラリ</p>



<p><code>@emotion/styled</code>：自分で部品の<strong>スタイルを定義する</strong>ライブラリ</p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc3">実際のコード</span></h2>



<p>下記の、統一感のあるフォームデザインを自分でCSSで整えるのは、意外と手間がかかります。</p>



<p>その点、MUIを使えばスタイルがあらかじめ用意されているため、<strong>見た目の整ったフォームを素早く実装することができます。</strong></p>



<figure class="wp-block-image size-large has-custom-border"><img loading="lazy" decoding="async" width="1024" height="724" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-14.17.39-1024x724.png" alt="MUIとは？ReactでおしゃれなUIがすぐ作れるライブラリを解説！" class="wp-image-3279" style="border-width:1px" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-14.17.39-1024x724.png 1024w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-14.17.39-300x212.png 300w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-14.17.39-768x543.png 768w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-14.17.39-1536x1085.png 1536w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-14.17.39.png 1738w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>送信ボタンを押下するとモーダル表示される</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="758" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-14.25.26-1024x758.png" alt="MUIとは？ReactでおしゃれなUIがすぐ作れるライブラリを解説！" class="wp-image-3280" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-14.25.26-1024x758.png 1024w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-14.25.26-300x222.png 300w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-14.25.26-768x569.png 768w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-14.25.26-1536x1138.png 1536w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-14.25.26.png 1750w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>import {
  AppBar,             // 画面上部に固定されるヘッダー
  Toolbar,            // ヘッダーの中の横並びレイアウト用
  Typography,         // 見出しや本文などのテキスト表示
  Container,          // 中央寄せ＆余白ありの全体レイアウト枠
  TextField,          // 入力フォーム（名前・メールなど）
  Button,             // 押せるボタン（送信・閉じるなど）
  Grid,               // 要素を縦や横に並べるレイアウト
  Card,               // 情報を囲って見せるパネル（カード）
  CardContent,        // カード内に配置する中身
  Box,                // スタイル調整や余白をつけるための箱
  Paper,              // 白背景＋影のついたパネル
  Dialog,             // ポップアップウィンドウ（モーダル）
  DialogTitle,        // モーダルのタイトル部分
  DialogContent,      // モーダルの本文部分
  DialogActions       // モーダルのボタン部分（閉じるなど）
} from &#8220;@mui/material&#8221;;


import { useState } from &#8220;react&#8221;;

function ContactForm() {
  const [open, setOpen] = useState(false);

  return (
    &lt;>
      {/* AppBar：上部ナビゲーション */}
      &lt;AppBar position=&#8221;static&#8221;>
        &lt;Toolbar>
          &lt;Typography variant=&#8221;h6&#8243;>ABC会社 &#8211; お問い合わせ&lt;/Typography>
        &lt;/Toolbar>
      &lt;/AppBar>

      {/* Container：中央レイアウト */}
      &lt;Container maxWidth=&#8221;sm&#8221; sx={{ mt: 4 }}>
        {/* Box：フォーム全体の囲み */}
        &lt;Box component={Paper} elevation={3} p={4}>
          &lt;Typography variant=&#8221;h5&#8243; gutterBottom>
            お問い合わせフォーム
          &lt;/Typography>

          {/* Grid：縦並びレイアウト */}
          &lt;Grid container spacing={2} direction=&#8221;column&#8221;>
            {/* 名前入力 */}
            &lt;Grid item>
              &lt;TextField label=&#8221;お名前&#8221; fullWidth variant=&#8221;outlined&#8221; />
            &lt;/Grid>

            {/* メールアドレス入力 */}
            &lt;Grid item>
              &lt;TextField label=&#8221;メールアドレス&#8221; fullWidth variant=&#8221;outlined&#8221; />
            &lt;/Grid>

            {/* 件名 */}
            &lt;Grid item>
              &lt;TextField label=&#8221;件名&#8221; fullWidth variant=&#8221;outlined&#8221; />
            &lt;/Grid>

            {/* 内容 */}
            &lt;Grid item>
              &lt;TextField
                label=&#8221;お問い合わせ内容&#8221;
                fullWidth
                multiline
                rows={4}
                variant=&#8221;outlined&#8221;
              />
            &lt;/Grid>

            {/* 送信ボタン */}
            &lt;Grid item>
              &lt;Button
                variant=&#8221;contained&#8221;
                color=&#8221;primary&#8221;
                fullWidth
                onClick={() => setOpen(true)}
              >
                送信する
              &lt;/Button>
            &lt;/Grid>
          &lt;/Grid>
        &lt;/Box>

        {/* Card：会社案内パネル */}
        &lt;Box mt={4}>
          &lt;Card>
            &lt;CardContent>
              &lt;Typography variant=&#8221;h6&#8243;>ABC会社について&lt;/Typography>
              &lt;Typography variant=&#8221;body2&#8243; color=&#8221;text.secondary&#8221;>
                〒100-0001 東京都中央区サンプル1-2-3 営業時間：平日 9:00〜18:00
                電話：03-1234-5678
              &lt;/Typography>
            &lt;/CardContent>
          &lt;/Card>
        &lt;/Box>
      &lt;/Container>

      {/* Dialog：送信後モーダル */}
      &lt;Dialog open={open} onClose={() => setOpen(false)}>
        &lt;DialogTitle>送信完了&lt;/DialogTitle>
        &lt;DialogContent>
          &lt;Typography>
            お問い合わせありがとうございました。ABC会社より折り返しご連絡いたします。
          &lt;/Typography>
        &lt;/DialogContent>
        &lt;DialogActions>
          &lt;Button onClick={() => setOpen(false)} autoFocus>
            閉じる
          &lt;/Button>
        &lt;/DialogActions>
      &lt;/Dialog>
    &lt;/>
  );
}

export default ContactForm;</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">AppBar</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">             </span><span style="color: #616E88">// 画面上部に固定されるヘッダー</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">Toolbar</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">            </span><span style="color: #616E88">// ヘッダーの中の横並びレイアウト用</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">Typography</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">         </span><span style="color: #616E88">// 見出しや本文などのテキスト表示</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">Container</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">          </span><span style="color: #616E88">// 中央寄せ＆余白ありの全体レイアウト枠</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">TextField</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">          </span><span style="color: #616E88">// 入力フォーム（名前・メールなど）</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">Button</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">             </span><span style="color: #616E88">// 押せるボタン（送信・閉じるなど）</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">Grid</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">               </span><span style="color: #616E88">// 要素を縦や横に並べるレイアウト</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">Card</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">               </span><span style="color: #616E88">// 情報を囲って見せるパネル（カード）</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">CardContent</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">        </span><span style="color: #616E88">// カード内に配置する中身</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">Box</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">                </span><span style="color: #616E88">// スタイル調整や余白をつけるための箱</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">Paper</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">              </span><span style="color: #616E88">// 白背景＋影のついたパネル</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">Dialog</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">             </span><span style="color: #616E88">// ポップアップウィンドウ（モーダル）</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">DialogTitle</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">        </span><span style="color: #616E88">// モーダルのタイトル部分</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">DialogContent</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">      </span><span style="color: #616E88">// モーダルの本文部分</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #8FBCBB">DialogActions</span><span style="color: #D8DEE9FF">       </span><span style="color: #616E88">// モーダルのボタン部分（閉じるなど）</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">@mui/material</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">useState</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">react</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">ContactForm</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">[</span><span style="color: #D8DEE9">open</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">setOpen</span><span style="color: #ECEFF4">]</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">useState</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">false</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> (</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* AppBar：上部ナビゲーション */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">AppBar</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">position</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">static</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Toolbar</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Typography</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">variant</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">h6</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF">ABC会社 - お問い合わせ</span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Typography</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Toolbar</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">AppBar</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* Container：中央レイアウト */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Container</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">maxWidth</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">sm</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">sx</span><span style="color: #81A1C1">={</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">mt</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">4</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">}&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* Box：フォーム全体の囲み */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Box</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">component</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">Paper</span><span style="color: #81A1C1">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">elevation</span><span style="color: #81A1C1">={</span><span style="color: #B48EAD">3</span><span style="color: #81A1C1">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">p</span><span style="color: #81A1C1">={</span><span style="color: #B48EAD">4</span><span style="color: #81A1C1">}&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Typography</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">variant</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">h5</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">gutterBottom</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            お問い合わせフォーム</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Typography</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* Grid：縦並びレイアウト */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Grid</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">container</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">spacing</span><span style="color: #81A1C1">={</span><span style="color: #B48EAD">2</span><span style="color: #81A1C1">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">direction</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">column</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* 名前入力 */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Grid</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">item</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">TextField</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">label</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">お名前</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">fullWidth</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">variant</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">outlined</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Grid</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* メールアドレス入力 */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Grid</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">item</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">TextField</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">label</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">メールアドレス</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">fullWidth</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">variant</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">outlined</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Grid</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* 件名 */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Grid</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">item</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">TextField</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">label</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">件名</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">fullWidth</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">variant</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">outlined</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Grid</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* 内容 */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Grid</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">item</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">TextField</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #8FBCBB">label</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">お問い合わせ内容</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #8FBCBB">fullWidth</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #8FBCBB">multiline</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #8FBCBB">rows</span><span style="color: #81A1C1">={</span><span style="color: #B48EAD">4</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #8FBCBB">variant</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">outlined</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Grid</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* 送信ボタン */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Grid</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">item</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Button</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #8FBCBB">variant</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">contained</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #8FBCBB">color</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">primary</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #8FBCBB">fullWidth</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #8FBCBB">onClick</span><span style="color: #81A1C1">={</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">setOpen</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                送信する</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Button</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Grid</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Grid</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Box</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* Card：会社案内パネル */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Box</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">mt</span><span style="color: #81A1C1">={</span><span style="color: #B48EAD">4</span><span style="color: #81A1C1">}&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Card</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">CardContent</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Typography</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">variant</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">h6</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF">ABC会社について</span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Typography</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Typography</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">variant</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">body2</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">color</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">text.secondary</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                〒100-0001 東京都中央区サンプル1-2-3 営業時間：平日 9:00〜18:00</span></span>
<span class="line"><span style="color: #D8DEE9FF">                電話：03-1234-5678</span></span>
<span class="line"><span style="color: #D8DEE9FF">              </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Typography</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">CardContent</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Card</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Box</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Container</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">{</span><span style="color: #616E88">/* Dialog：送信後モーダル */</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Dialog</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">open</span><span style="color: #81A1C1">={</span><span style="color: #D8DEE9">open</span><span style="color: #81A1C1">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">onClose</span><span style="color: #81A1C1">={</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">setOpen</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">false</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">}&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">DialogTitle</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF">送信完了</span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">DialogTitle</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">DialogContent</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Typography</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            お問い合わせありがとうございました。ABC会社より折り返しご連絡いたします。</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Typography</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">DialogContent</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">DialogActions</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">Button</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">onClick</span><span style="color: #81A1C1">={</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">setOpen</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">false</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">autoFocus</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            閉じる</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Button</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">DialogActions</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;/</span><span style="color: #8FBCBB">Dialog</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  )</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">export</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">default</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ContactForm</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-normal-card">
<a href="https://it-bokenki.com/2025/06/11/zod/" title="Zodとは？React Hook Formとの連携でバリデーション実装" 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="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-1-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-1-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-1-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-1-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">Zodとは？React Hook Formとの連携でバリデーション実装</div><div class="blogcard-snippet internal-blogcard-snippet">TypeScriptで使えるバリデーションライブラリ「Zod」の基本と、React Hook Formとの連携方法を解説します。</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://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:0px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc4">こんなときにMUIはおすすめ！</span></h2>



<ul class="wp-block-list">
<li>デザインの統一感がほしいとき</li>



<li>手早く開発を進めたいとき</li>



<li>チーム開発で見た目を揃えたいとき</li>



<li>バリデーション付きのフォームなど、複雑なUIを早く実装したいとき</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc5">注意点・デメリット</span></h2>



<ul class="wp-block-list">
<li>クラス名で直接装飾しにくく、カスタマイズが難しいと感じることがある</li>



<li>内部でEmotion（CSS-in-JS）を使っているため、<strong><span class="marker">CSSの書き方が普通と少し違う</span></strong></li>
</ul>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<p><strong>◆ 普通のCSSの書き方</strong></p>



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



<p><strong>◆ Emotion（CSS-in-JS）を使った書き方（MUIの場合）</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>import { styled } from &#8216;@mui/material/styles&#8217;;

const CustomButton = styled(&#8216;button&#8217;)({
  backgroundColor: &#8216;red&#8217;,
});
</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">styled</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">@mui/material/styles</span><span style="color: #ECEFF4">&#39;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CustomButton</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">styled</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">button</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">)(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">backgroundColor</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">red</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="text-align: center;"><a rel="nofollow" href="https://px.a8.net/svt/ejp?a8mat=3TB6RG+CDC99U+2JK4+3B3ZA9">
<img loading="lazy" decoding="async" border="0" width="300" height="250" alt="" src="https://www26.a8.net/svt/bgt?aid=230629372748&#038;wid=001&#038;eno=01&#038;mid=s00000011866020006000&#038;mc=1"></a>
<img loading="lazy" decoding="async" border="0" width="1" height="1" src="https://www11.a8.net/0.gif?a8mat=3TB6RG+CDC99U+2JK4+3B3ZA9" alt=""></div><p>The post <a href="https://it-bokenki.com/2025/06/14/mui/">MUIとは？ReactでおしゃれなUIがすぐ作れるライブラリを解説！</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://it-bokenki.com/2025/06/14/mui/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Zodとは？React Hook Formとの連携でバリデーション実装</title>
		<link>https://it-bokenki.com/2025/06/11/zod/</link>
					<comments>https://it-bokenki.com/2025/06/11/zod/#respond</comments>
		
		<dc:creator><![CDATA[てんハロ運営者]]></dc:creator>
		<pubDate>Wed, 11 Jun 2025 07:07:22 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[フロントエンド]]></category>
		<guid isPermaLink="false">https://it-bokenki.com/?p=3026</guid>

					<description><![CDATA[<p>でじぼうです。 TypeScriptのフォーム実装でよく登場する、Zodのバリデーション記述についてまとめました。 Zodとは？ Zod（ゾッド）は、TypeScript向けのスキーマバリデーションライブラリです。 簡単 [&#8230;]</p>
<p>The post <a href="https://it-bokenki.com/2025/06/11/zod/">Zodとは？React Hook Formとの連携でバリデーション実装</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>でじぼうです。</p>



<p>TypeScriptのフォーム実装でよく登場する、<code>Zod</code>のバリデーション記述についてまとめました。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="でじぼう" class="speech-icon-image"/></figure><div class="speech-name">でじぼう</div></div><div class="speech-balloon">
<p>この記事は下記の方がおすすめ！<br></p>



<ul class="wp-block-list">
<li style="font-size:15px">Zodってなに？</li>



<li style="font-size:15px">バリデーションはどんな種類があるの？</li>



<li style="font-size:15px">バリデーション実行はどのタイミング？</li>
</ul>
</div></div>



<div style="text-align: center;">
<a rel="nofollow" href="https://px.a8.net/svt/ejp?a8mat=3TB6RG+C3TBLE+4RIG+BYT9D">
<img loading="lazy" decoding="async" border="0" width="468" height="60" alt="" src="https://www26.a8.net/svt/bgt?aid=230629372732&#038;wid=001&#038;eno=01&#038;mid=s00000022228002010000&#038;mc=1"></a>
<img loading="lazy" decoding="async" border="0" width="1" height="1" src="https://www16.a8.net/0.gif?a8mat=3TB6RG+C3TBLE+4RIG+BYT9D" alt="">
</div>




<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc1">Zodとは？</span></h2>



<figure class="wp-block-image aligncenter size-large is-resized has-custom-border"><img loading="lazy" decoding="async" width="1024" height="468" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-11-15.03.23-1024x468.png" alt="Zodとは？React Hook Formとの連携でバリデーション実装をスマートに" class="wp-image-3040" style="border-width:1px;width:618px;height:auto" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-11-15.03.23-1024x468.png 1024w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-11-15.03.23-300x137.png 300w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-11-15.03.23-768x351.png 768w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-11-15.03.23.png 1300w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Zod（ゾッド）は、TypeScript向けのスキーマバリデーションライブラリです。</p>



<p>簡単に言うと、<span class="marker-under"><strong>「このデータはこの形であるべき！」というルールをコードで定義し、そのルール通りになっているかチェックする仕組み</strong></span>です。</p>



<p>特に、ReactやNext.jsなどのフレームワークと組み合わせて使われる<strong>React Hook Form</strong>と相性が良く、<strong>フロントエンドのフォームバリデーション</strong>でよく利用されます。</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc2">よく使うバリデーション一覧</span></h2>



<p>下記に、よく利用する<code>Zod</code>のバリデーション一覧をまとめました。</p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><thead><tr><th>チェック内容</th><th>Zod記述</th><th>エラーメッセージ</th></tr></thead><tbody><tr><td>未入力(必須）</td><td><span class="marker">z.string().min</span>(1, &#8220;名前を入力してください&#8221;)</td><td>名前を入力してください</td></tr><tr><td>文字数の最小制限</td><td><span class="marker">z.string().min</span>(3, &#8220;3文字以上で入力してください&#8221;)</td><td>3文字以上で入力してください</td></tr><tr><td>文字数の最大制限</td><td><span class="marker">z.string().max</span>(20, &#8220;20文字以内で入力してください&#8221;)</td><td>20文字以内で入力してください</td></tr><tr><td>メール形式</td><td><span class="marker">z.string().email</span>(&#8220;正しいメールアドレスを入力してください&#8221;)</td><td>正しいメールアドレスを入力してください</td></tr><tr><td>正規表現チェック</td><td><span class="marker">z.string().regex</span>(/^\d+$/, &#8220;数字のみで入力してください&#8221;)</td><td>数字のみで入力してください</td></tr><tr><td>特定の文字列のみ許可</td><td><span class="marker">z.enum</span>([&#8220;男&#8221;, &#8220;女&#8221;, &#8220;未回答&#8221;])</td><td>性別を選択してください</td></tr><tr><td>数値の範囲</td><td><span class="marker">z.number().min</span>(1, &#8220;1以上の数値を入力してください&#8221;)</td><td>1以上の数値を入力してください</td></tr><tr><td>真偽値のチェック</td><td><span class="marker">z.boolean</span>().refine(val =&gt; val, &#8220;同意が必要です&#8221;)</td><td>同意が必要です</td></tr><tr><td>日付の存在確認</td><td><span class="marker">z.date</span>({ required_error: &#8220;日付を選択してください&#8221; })</td><td>日付を選択してください</td></tr><tr><td>nullを許容</td><td><span class="marker">z.string().nullable()</span></td><td>※nullもOKな項目に使用</td></tr><tr><td>オプショナル</td><td><span class="marker">z.string().optional()</span></td><td>※未入力（undefined）もOK</td></tr></tbody></table></figure>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc3">modeの違いとタイミング解説（React Hook Form向け）</span></h2>



<p>React Hook Formでは、いつバリデーションを実行するかを <code>mode</code> で指定できます。</p>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><thead><tr><th>mode設定値</th><th>タイミングの説明</th><th>用途例</th></tr></thead><tbody><tr><td><span class="marker"><strong>onSubmit</strong></span></td><td>フォーム送信時のみ実行</td><td>エラー表示を最小限にしたい時</td></tr><tr><td><span class="marker"><strong>onChange</strong></span></td><td>入力のたびに（1文字でも入力すると即時）</td><td>即時エラー表示が必要な時</td></tr><tr><td><span class="marker"><strong>onBlur</strong></span></td><td>フォーカスが外れたときに実行</td><td>入力中は集中させたい時</td></tr><tr><td><strong><span class="marker">onTouched</span></strong></td><td>一度触れてからフォーカスが外れたときに実行</td><td>初回は控えめ・2回目以降に即バリデーション</td></tr><tr><td><span class="marker"><strong>all</strong></span></td><td>onChange＋onBlur＋onSubmitすべて実行</td><td>厳格なバリデーションが必要な場合</td></tr></tbody></table></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>下記は、mode: <code>onChange</code> を指定した場合</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const {
  register,           // 各フォーム要素にバリデーションを適用するための関数
  handleSubmit,       // フォーム送信時の処理をまとめる関数
  formState: { errors } // バリデーションエラーの状態を管理するオブジェクト
} = useForm({
  mode: &#8220;onChange&#8221;     // 入力が変わるたびにバリデーションを実行する
});</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">register</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">           </span><span style="color: #616E88">// 各フォーム要素にバリデーションを適用するための関数</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">handleSubmit</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">       </span><span style="color: #616E88">// フォーム送信時の処理をまとめる関数</span></span>
<span class="line"><span style="color: #D8DEE9FF">  formState</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">errors</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// バリデーションエラーの状態を管理するオブジェクト</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">useForm</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">mode</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">onChange</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">     </span><span style="color: #616E88">// 入力が変わるたびにバリデーションを実行する</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p>下記は、mode を省略した場合。デフォルトの <code>onSubmit</code> に設定される</p>



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



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-popular is-style-normal-card">
<a href="https://it-bokenki.com/2025/06/11/typescript-optional-null/" title="【TypeScript】date?: Date | null の意味をやさしく解説！" 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="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【TypeScript】date?: Date | null の意味をやさしく解説！</div><div class="blogcard-snippet internal-blogcard-snippet">TypeScriptのdate?: Date | nullの意味を初心者向けにやさしく解説します。</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://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:0px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc4">実装コード</span></h2>



<p>Zodを使用したバリデーションチェックの実装例をご紹介します。</p>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc5">使用している技術</span></h3>



<p><strong>言語</strong>：TypeScript</p>



<ul class="wp-block-list">
<li><a class="" href="https://react.dev/"><code>React</code></a>：UIフレームワーク</li>



<li><a class="" href="https://react-hook-form.com/"><code>React Hook Form</code></a>：フォーム処理ライブラリ</li>



<li><a class="" href="https://zod.dev/"><code>Zod</code></a>：バリデーションスキーマライブラリ</li>



<li><strong>zodResolver</strong>：ZodとReact Hook Formを接続<br></li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc6">実装内容</span></h3>



<p><strong>名前・メールアドレス・電話番号の入力フォーム</strong>を作成<br>入力のたびにバリデーションが実行され、間違っていれば即エラーメッセージを表示</p>



<ul class="wp-block-list">
<li>未入力チェック（全項目）</li>



<li>メールアドレス形式のチェック</li>



<li>電話番号が数字やハイフンのみかを正規表現でチェック</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>import { useForm } from &#8220;react-hook-form&#8221;;
import { z } from &#8220;zod&#8221;;
import { zodResolver } from &#8220;@hookform/resolvers/zod&#8221;;

// 入力項目のバリデーションルール
const schema = z.object({
  name: z.string().min(1, &#8220;名前を入力してください&#8221;),
  email: z
    .string()
    .min(1, &#8220;メールアドレスを入力してください&#8221;)
    .email(&#8220;正しいメールアドレス形式で入力してください&#8221;),
  tel: z
    .string()
    .min(1, &#8220;電話番号を入力してください&#8221;)
    .regex(/^[0-9\-]+$/, &#8220;数字またはハイフンのみで入力してください&#8221;),
});

// Zodスキーマからフォームの型を自動生成
type FormData = z.infer&lt;typeof schema>;

export default function ContactForm() {
  // useFormでフォームを初期化
  const {
    register, // 各inputにバリデーションを紐づける
    handleSubmit, // フォーム送信時にバリデーションを実行
    formState: { errors }, // 各項目のバリデーションエラー情報
  } = useForm&lt;FormData>({
    resolver: zodResolver(schema), // Zodで定義したスキーマを使う
    mode: &#8220;onChange&#8221;,              // 入力ごとにバリデーション実行
  });

  // バリデーション成功時の処理
  const onSubmit = (data: FormData) => {
    console.log(data);
  };

  return (
    &lt;form onSubmit={handleSubmit(onSubmit)}>
      &lt;input {&#8230;register(&#8220;name&#8221;)} placeholder=&#8221;名前&#8221; />　// registerの記載でチェック対象とする
      {errors.name &amp;&amp; &lt;p>{errors.name.message}&lt;/p>}　　// エラーメッセージの表示

      &lt;input {&#8230;register(&#8220;email&#8221;)} placeholder=&#8221;メールアドレス&#8221; />
      {errors.email &amp;&amp; &lt;p>{errors.email.message}&lt;/p>}

      &lt;input {&#8230;register(&#8220;tel&#8221;)} placeholder=&#8221;電話番号&#8221; />
      {errors.tel &amp;&amp; &lt;p>{errors.tel.message}&lt;/p>}

      &lt;button type=&#8221;submit&#8221;>送信&lt;/button>
    &lt;/form>
  );
}</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">useForm</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">react-hook-form</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">zod</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">zodResolver</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">@hookform/resolvers/zod</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// 入力項目のバリデーションルール</span></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">schema</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">min</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">名前を入力してください</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">email</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">min</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">メールアドレスを入力してください</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">email</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">正しいメールアドレス形式で入力してください</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">tel</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">min</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">電話番号を入力してください</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">regex</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">/</span><span style="color: #81A1C1">^</span><span style="color: #ECEFF4">[</span><span style="color: #EBCB8B">0-9\-</span><span style="color: #ECEFF4">]</span><span style="color: #81A1C1">+$</span><span style="color: #ECEFF4">/</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">数字またはハイフンのみで入力してください</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Zodスキーマからフォームの型を自動生成</span></span>
<span class="line"><span style="color: #81A1C1">type</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">FormData</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">z</span><span style="color: #ECEFF4">.</span><span style="color: #8FBCBB">infer</span><span style="color: #ECEFF4">&lt;</span><span style="color: #81A1C1">typeof</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">schema</span><span style="color: #ECEFF4">&gt;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">export</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">default</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">ContactForm</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// useFormでフォームを初期化</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">register</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// 各inputにバリデーションを紐づける</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">handleSubmit</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// フォーム送信時にバリデーションを実行</span></span>
<span class="line"><span style="color: #D8DEE9FF">    formState</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">errors</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">},</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// 各項目のバリデーションエラー情報</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">useForm</span><span style="color: #ECEFF4">&lt;</span><span style="color: #8FBCBB">FormData</span><span style="color: #ECEFF4">&gt;</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">resolver</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">zodResolver</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">schema</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Zodで定義したスキーマを使う</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">mode</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">onChange</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">              </span><span style="color: #616E88">// 入力ごとにバリデーション実行</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// バリデーション成功時の処理</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">onSubmit</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">data</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">FormData</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">log</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">data</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> (</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">form</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">onSubmit</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">{</span><span style="color: #88C0D0">handleSubmit</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">onSubmit</span><span style="color: #ECEFF4">)}</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">input</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #81A1C1">...</span><span style="color: #D8DEE9">register</span><span style="color: #D8DEE9FF">(&quot;</span><span style="color: #D8DEE9">name</span><span style="color: #D8DEE9FF">&quot;)</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">placeholder</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">名前</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/&gt;</span><span style="color: #D8DEE9FF">　</span><span style="color: #616E88">// registerの記載でチェック対象とする</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">errors</span><span style="color: #D8DEE9FF">.</span><span style="color: #D8DEE9">name</span><span style="color: #D8DEE9FF"> &amp;&amp; &lt;</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF">&gt;</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">errors</span><span style="color: #D8DEE9FF">.</span><span style="color: #D8DEE9">name</span><span style="color: #D8DEE9FF">.</span><span style="color: #D8DEE9">message</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">&lt;/</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF">&gt;</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">　　</span><span style="color: #616E88">// エラーメッセージの表示</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">input</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #81A1C1">...</span><span style="color: #D8DEE9">register</span><span style="color: #D8DEE9FF">(&quot;</span><span style="color: #D8DEE9">email</span><span style="color: #D8DEE9FF">&quot;)</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">placeholder</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">メールアドレス</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">errors</span><span style="color: #D8DEE9FF">.</span><span style="color: #D8DEE9">email</span><span style="color: #D8DEE9FF"> &amp;&amp; &lt;</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF">&gt;</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">errors</span><span style="color: #D8DEE9FF">.</span><span style="color: #D8DEE9">email</span><span style="color: #D8DEE9FF">.</span><span style="color: #D8DEE9">message</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">&lt;/</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF">&gt;</span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">input</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #81A1C1">...</span><span style="color: #D8DEE9">register</span><span style="color: #D8DEE9FF">(&quot;</span><span style="color: #D8DEE9">tel</span><span style="color: #D8DEE9FF">&quot;)</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">placeholder</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">電話番号</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">errors</span><span style="color: #D8DEE9FF">.</span><span style="color: #D8DEE9">tel</span><span style="color: #D8DEE9FF"> &amp;&amp; &lt;</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF">&gt;</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">errors</span><span style="color: #D8DEE9FF">.</span><span style="color: #D8DEE9">tel</span><span style="color: #D8DEE9FF">.</span><span style="color: #D8DEE9">message</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">&lt;/</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF">&gt;</span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">button</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">type</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">submit</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9">送信</span><span style="color: #81A1C1">&lt;/</span><span style="color: #D8DEE9">button</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;/</span><span style="color: #D8DEE9">form</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  )</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc7">よくあるミスや注意点</span></h2>



<ul class="wp-block-list">
<li><code>min(1)</code> だけだと空白（スペース）だけの入力を許してしまう <br>→ <span class="marker"><strong><code>.refine(val =&gt; val.trim() !== '')</code> を追加すると◎</strong></span></li>



<li><code>null</code> を許容したい場合は <code>.nullable()</code> を使う<br>→ 例：<code>z.string().nullable()</code><br>    これは <code>null</code> を受け入れ、未入力とは別の扱いになります。</li>



<li><strong><span class="marker"><code>zodResolver</code> を使わないとReact Hook Formとの連携ができない</span></strong>ので注意</li>
</ul>



<p></p><p>The post <a href="https://it-bokenki.com/2025/06/11/zod/">Zodとは？React Hook Formとの連携でバリデーション実装</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://it-bokenki.com/2025/06/11/zod/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
