<?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>useImperativeHandle</title>
	<atom:link href="https://techgrowup.net/tag/useimperativehandle/feed/" rel="self" type="application/rss+xml" />
	<link>https://techgrowup.net</link>
	<description>エンジニアを強くする</description>
	<lastBuildDate>Wed, 30 Apr 2025 20:00:00 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://techgrowup.net/wp-content/uploads/2021/05/hp-icon-150x150.png</url>
	<title>useImperativeHandle</title>
	<link>https://techgrowup.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>useRef徹底ガイド──DOMアクセスからミューテーション管理まで</title>
		<link>https://techgrowup.net/react-useref/</link>
					<comments>https://techgrowup.net/react-useref/?noamp=mobile#respond</comments>
		
		<dc:creator><![CDATA[techgrowup]]></dc:creator>
		<pubDate>Wed, 30 Apr 2025 20:00:00 +0000</pubDate>
				<category><![CDATA[React]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[DOM参照]]></category>
		<category><![CDATA[forwardRef]]></category>
		<category><![CDATA[ref]]></category>
		<category><![CDATA[useImperativeHandle]]></category>
		<category><![CDATA[useRef]]></category>
		<category><![CDATA[コールバックref]]></category>
		<category><![CDATA[ミューテーション]]></category>
		<guid isPermaLink="false">https://techgrowup.net/?p=2832</guid>

					<description><![CDATA[useRefとは？ ReactのuseRefフックは、レンダー間で変化しても再レンダーを引き起こさない「箱」を提供します。返されるオブジェクトは{ current: 値 }という形で、コンポーネントのライフサイクル全体を [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">useRefとは？</h2>



<p class="wp-block-paragraph">Reactの<code>useRef</code>フックは、レンダー間で変化しても再レンダーを引き起こさない「箱」を提供します。返されるオブジェクトは<code>{ current: 値 }</code>という形で、コンポーネントのライフサイクル全体を通じて同じ参照を保持します。主な用途は次の二つです。</p>



<ol class="wp-block-list">
<li><strong>DOM要素への参照</strong>：フォーム入力フォーカスやスクロール位置制御</li>



<li><strong>ミューテーション値の保持</strong>：レンダー外で更新されるカウンタや外部ライブラリのインスタンス</li>
</ol>



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

function TextInputFocus() {
  const inputRef = useRef(null);

  useEffect(() =&gt; {
    inputRef.current.focus();
  }, []);

  return &lt;input ref={inputRef} placeholder=&quot;自動でフォーカス&quot; /&gt;;
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #C586C0">import</span><span style="color: #D4D4D4"> { </span><span style="color: #9CDCFE">useRef</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">useEffect</span><span style="color: #D4D4D4"> } </span><span style="color: #C586C0">from</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;react&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">TextInputFocus</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">inputRef</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">useRef</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">useEffect</span><span style="color: #D4D4D4">(() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">inputRef</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">current</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">focus</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">  }, []);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">input</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ref</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">inputRef</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">placeholder</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;自動でフォーカス&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<h2 class="wp-block-heading">仕組みと特徴</h2>



<ul class="wp-block-list">
<li><code>useRef(initialValue)</code> はレンダーのたびに <strong>同じオブジェクト</strong> を返す</li>



<li><code>ref.current</code> の変更は React の再レンダーをトリガーしない</li>



<li>オブジェクト参照自体は固定だが <code>current</code> プロパティは自由に書き換え可能</li>
</ul>



<p class="wp-block-paragraph">この振る舞いにより、<strong>状態のように保持しつつUIに影響を与えないデータ</strong> を格納できます。</p>



<h2 class="wp-block-heading">DOMリファレンスの実践例</h2>



<h3 class="wp-block-heading">フォームのフォーカス管理</h3>



<p class="wp-block-paragraph">複数ステップのフォームで次の入力要素へフォーカスを移すとき、<code>useRef</code> が活躍します。</p>



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

  useEffect(() =&gt; {
    if (step === 1) step1Ref.current.focus();
    if (step === 2) step2Ref.current.focus();
  }, [step]);

  return (
    &lt;&gt;
      {step === 1 &amp;&amp; &lt;input ref={step1Ref} /&gt;}
      {step === 2 &amp;&amp; &lt;input ref={step2Ref} /&gt;}
      &lt;button onClick={() =&gt; setStep(s =&gt; s + 1)}&gt;次へ&lt;/button&gt;
    &lt;/&gt;
  );
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">MultiStepForm</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">step1Ref</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">useRef</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">step2Ref</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">useRef</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> [</span><span style="color: #4FC1FF">step</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">setStep</span><span style="color: #D4D4D4">] = </span><span style="color: #DCDCAA">useState</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">useEffect</span><span style="color: #D4D4D4">(() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">step</span><span style="color: #D4D4D4"> === </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">) </span><span style="color: #9CDCFE">step1Ref</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">current</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">focus</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">step</span><span style="color: #D4D4D4"> === </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">) </span><span style="color: #9CDCFE">step2Ref</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">current</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">focus</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">  }, [</span><span style="color: #9CDCFE">step</span><span style="color: #D4D4D4">]);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">step</span><span style="color: #D4D4D4"> === </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> &amp;&amp; </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">input</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ref</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">step1Ref</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span><span style="color: #569CD6">}</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">step</span><span style="color: #D4D4D4"> === </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4"> &amp;&amp; </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">input</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ref</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">step2Ref</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span><span style="color: #569CD6">}</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">button</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">onClick</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #D4D4D4">() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">setStep</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">s</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">s</span><span style="color: #D4D4D4"> + </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">)</span><span style="color: #569CD6">}</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">次へ</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">button</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;/&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">  );</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<h3 class="wp-block-heading">スクロール制御</h3>



<p class="wp-block-paragraph">チャットアプリで新しいメッセージ追加時に最下部までスクロールする例。</p>



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

  useEffect(() =&gt; {
    bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);

  return (
    &lt;div className=&quot;chat-area&quot;&gt;
      {messages.map(m =&gt; &lt;p key={m.id}&gt;{m.text}&lt;/p&gt;)}
      &lt;div ref={bottomRef} /&gt;
    &lt;/div&gt;
  );
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">ChatWindow</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">messages</span><span style="color: #D4D4D4"> }) {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">bottomRef</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">useRef</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">useEffect</span><span style="color: #D4D4D4">(() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">bottomRef</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">current</span><span style="color: #D4D4D4">?.</span><span style="color: #DCDCAA">scrollIntoView</span><span style="color: #D4D4D4">({ </span><span style="color: #9CDCFE">behavior:</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;smooth&#39;</span><span style="color: #D4D4D4"> });</span></span>
<span class="line"><span style="color: #D4D4D4">  }, [</span><span style="color: #9CDCFE">messages</span><span style="color: #D4D4D4">]);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">div</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">className</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;chat-area&quot;</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">messages</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">map</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">m</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">p</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">key</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">m</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">id</span><span style="color: #569CD6">}</span><span style="color: #808080">&gt;</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">m</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">text</span><span style="color: #569CD6">}</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">p</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">)</span><span style="color: #569CD6">}</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">div</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ref</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">bottomRef</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">div</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">  );</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<h2 class="wp-block-heading">ミューテーション値の保持</h2>



<h3 class="wp-block-heading">レンダー回数を数える</h3>



<p class="wp-block-paragraph">状態にすると無限ループするような値は <code>useRef</code> で保持。</p>



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



<h3 class="wp-block-heading">setIntervalのIDを保持</h3>



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

  const start = () =&gt; {
    if (intervalRef.current === null) {
      intervalRef.current = setInterval(() =&gt; setCount(c =&gt; c + 1), 1000);
    }
  };

  const stop = () =&gt; {
    clearInterval(intervalRef.current);
    intervalRef.current = null;
  };

  useEffect(() =&gt; stop, []); // アンマウント時に停止

  return &lt;&gt;
    &lt;p&gt;{count} 秒経過&lt;/p&gt;
    &lt;button onClick={start}&gt;開始&lt;/button&gt;
    &lt;button onClick={stop}&gt;停止&lt;/button&gt;
  &lt;/&gt;;
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">Timer</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">intervalRef</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">useRef</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> [</span><span style="color: #4FC1FF">count</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">setCount</span><span style="color: #D4D4D4">] = </span><span style="color: #DCDCAA">useState</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">start</span><span style="color: #D4D4D4"> = () </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">intervalRef</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">current</span><span style="color: #D4D4D4"> === </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">intervalRef</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">current</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">setInterval</span><span style="color: #D4D4D4">(() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">setCount</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">c</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">c</span><span style="color: #D4D4D4"> + </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">), </span><span style="color: #B5CEA8">1000</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">  };</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">stop</span><span style="color: #D4D4D4"> = () </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">clearInterval</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">intervalRef</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">current</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">intervalRef</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">current</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">  };</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">useEffect</span><span style="color: #D4D4D4">(() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">stop</span><span style="color: #D4D4D4">, []); </span><span style="color: #6A9955">// アンマウント時に停止</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #808080">&lt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">p</span><span style="color: #808080">&gt;</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">count</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> 秒経過</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">p</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">button</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">onClick</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">start</span><span style="color: #569CD6">}</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">開始</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">button</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">button</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">onClick</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">stop</span><span style="color: #569CD6">}</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">停止</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">button</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #808080">&lt;/&gt;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<h2 class="wp-block-heading">forwardRefと組み合わせる</h2>



<p class="wp-block-paragraph">親コンポーネントから子のDOMへ直接アクセスする場合は <code>forwardRef</code> が必要です。</p>



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

function Parent() {
  const inputRef = useRef(null);
  return &lt;&gt;
    &lt;FancyInput ref={inputRef} /&gt;
    &lt;button onClick={() =&gt; inputRef.current.focus()}&gt;フォーカス&lt;/button&gt;
  &lt;/&gt;;
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">FancyInput</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">React</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">forwardRef</span><span style="color: #D4D4D4">((</span><span style="color: #9CDCFE">props</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">ref</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">input</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">className</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;fancy&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ref</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">ref</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">{</span><span style="color: #D4D4D4">...</span><span style="color: #9CDCFE">props</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">});</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">Parent</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">inputRef</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">useRef</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #808080">&lt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;</span><span style="color: #4EC9B0">FancyInput</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ref</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">inputRef</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">button</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">onClick</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #D4D4D4">() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">inputRef</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">current</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">focus</span><span style="color: #D4D4D4">()</span><span style="color: #569CD6">}</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">フォーカス</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">button</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #808080">&lt;/&gt;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<h2 class="wp-block-heading">useImperativeHandleで公開APIを制御</h2>



<p class="wp-block-paragraph">子コンポーネント側で <code>ref</code> 経由の公開メソッドをカスタマイズできます。</p>



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

function DrawingApp() {
  const canvasRef = useRef();
  return &lt;&gt;
    &lt;Canvas ref={canvasRef} /&gt;
    &lt;button onClick={() =&gt; canvasRef.current.clear()}&gt;クリア&lt;/button&gt;
  &lt;/&gt;;
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">Canvas</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">React</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">forwardRef</span><span style="color: #D4D4D4">((</span><span style="color: #9CDCFE">props</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">ref</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">canvasRef</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">useRef</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">useImperativeHandle</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">ref</span><span style="color: #D4D4D4">, () </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> ({</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">clear</span><span style="color: #9CDCFE">:</span><span style="color: #D4D4D4"> () </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">canvasRef</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">current</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">getContext</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39;2d&#39;</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">clearRect</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">,</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">,</span><span style="color: #B5CEA8">300</span><span style="color: #D4D4D4">,</span><span style="color: #B5CEA8">150</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">  }));</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">canvas</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ref</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">canvasRef</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">width</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #B5CEA8">300</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">height</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #B5CEA8">150</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">});</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">DrawingApp</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">canvasRef</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">useRef</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #808080">&lt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;</span><span style="color: #4EC9B0">Canvas</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ref</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #9CDCFE">canvasRef</span><span style="color: #569CD6">}</span><span style="color: #D4D4D4"> </span><span style="color: #808080">/&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">button</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">onClick</span><span style="color: #D4D4D4">=</span><span style="color: #569CD6">{</span><span style="color: #D4D4D4">() </span><span style="color: #569CD6">=&gt;</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">canvasRef</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">current</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">clear</span><span style="color: #D4D4D4">()</span><span style="color: #569CD6">}</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">クリア</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">button</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #808080">&lt;/&gt;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<h2 class="wp-block-heading">コールバックrefとの比較</h2>



<figure class="wp-block-table"><div class="scrollable-table"><table class="has-fixed-layout"><thead><tr><th>種類</th><th>設定方法</th><th>特徴</th></tr></thead><tbody><tr><td>string ref</td><td><code>ref="myRef"</code></td><td>レガシー、廃止予定</td></tr><tr><td>callback ref</td><td><code>ref={node =&gt; { ... }}</code></td><td>動的に複数refや条件分岐を管理</td></tr><tr><td>useRef + ref属性</td><td><code>const r=useRef(); … ref={r}</code></td><td>一般的。オブジェクトに一度だけセット</td></tr></tbody></table></div></figure>



<h2 class="wp-block-heading">パフォーマンスに与える影響</h2>



<p class="wp-block-paragraph"><code>useRef</code> はレンダーをトリガーしないため、頻繁に変化する値を保持してもコストは低い。ただし <code>current</code> の変更にUIを反映したい場合は、別途 <code>useState</code> と組み合わせる必要がある。</p>



<h2 class="wp-block-heading">よくある落とし穴</h2>



<ol class="wp-block-list">
<li><strong>refがnullのままアクセス</strong>
<ul class="wp-block-list">
<li>初回レンダー直後はまだDOMがセットされておらずnull。<code>useEffect</code> の中で読む。</li>
</ul>
</li>



<li><strong>currentを書き換えても画面が更新されない</strong>
<ul class="wp-block-list">
<li><code>useRef</code>は状態管理ではない。UIに反映が必要なら <code>useState</code> を使う。</li>
</ul>
</li>



<li><strong>依存配列にref.currentを入れてしまう</strong>
<ul class="wp-block-list">
<li><code>ref.current</code> の値が変わっても依存配列は検知しない。監視には別状態が必要。</li>
</ul>
</li>
</ol>



<h2 class="wp-block-heading">総括</h2>



<p class="wp-block-paragraph"><code>useRef</code> は <strong>DOMアクセス</strong> と <strong>ミューテーション値の永続化</strong> を実現する万能ポケットです。再レンダーコストを抑えつつ、状態とは異なる形で情報を保持できるため、フォーム・アニメーション・外部ライブラリ統合など多様な場面で活用できます。ポイントは「UI描画に関与しない値」を見極め、状態との役割分担を明確にすることです。</p>



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