ReactでinputをfocusするにはuseRefとuseEffectが必要

useRefだけではマウント時にfocusされない

Reactのコードを確認中にinputをfocusさせようとしている、以下のようなコードを見かけました。

TSX
import { useRef } from 'react'

function App() {
  const inputRef = useRef<HTMLInputElement>(null)

  if (inputRef.current) {
    inputRef.current.focus()
  }

  return (
    <div>
      <h2>検索</h2>
      <input ref={inputRef} type="search" />
    </div>
  )
}

export default App

一見するとエラーも出ておらず問題ないように見えますが、実際に確認するとinputがfocusされません。

React input focus NG pattern

useEffectでコンポーネントのマウント後に実行する

前述のコードでは、inputRef.current.focus()が実行される時点で、input要素がDOMに追加されていないため、inputRef.currentがnullのままです。

そのため、フォーカスを設定するコードをuseEffectフックの中に入れる必要があります。

TSX
import { useRef, useEffect } from 'react'

function App() {
  const inputRef = useRef<HTMLInputElement>(null)

  useEffect(() => {
    if (inputRef.current) {
      inputRef.current.focus()
    }
  }, [])

  return (
    <div>
      <h2>検索</h2>
      <input ref={inputRef} type="search" />
    </div>
  )
}

export default App

React input focus OK pattern

このような処理はConsoleなどにエラーが表示されないため、focus()を使用する際は注意が必要です。

※ クリックイベントなどでなければautofocus属性を使用する選択肢もあります。