React Developer ToolsのHighlight機能にはバグがあるので注意

React Developer Toolsとは

React Developer ToolsはReactをデバッグするための公式ツールで、主に以下の5つの機能があります。

  1. コンポーネントの再レンダリング検出
  2. コンポーネントの階層構造を表示
  3. コンポーネントのpropsやstateを確認・変更
  4. パフォーマンスプロファイリング
  5. React hookのデバッグ

この機能の中で一番使用されている機能は「コンポーネントの再レンダリング検出」です。

Reactはコンポーネントが更新されたときに再レンダリングを行いますが、すべての再レンダリングが必要とは限りません。

例えば、あるコンポーネントの状態やpropsが変わらないにもかかわらず再レンダリングが発生すると、CPUリソースが無駄に消費され、動作が重くなります。

そのため、Reactを使用してWebパフォーマンスの良いWebサイトやWebアプリを制作する人は、必ずと言って良いほどReact Developer Toolsで無駄な再レンダリングがないかチェックしています。

React Developer Toolsはブラウザ拡張機能をインストールすれば使用可能です。

React Developer Tools

Chromeの場合は拡張機能をインストールすると「Reactが読み込まれているWebページ」でデベロッパーツールを開くと、一番右のほうに⚛️Componentsと⚛️Profilerが追加されていることが確認できます。

※ 表示されていない場合は一番右の >> をクリックしてください。

コンポーネントの再レンダリング検出方法

React Developer Toolsで再レンダリングを確認するには、⚛️Componentsを開いて、⚙️歯車アイコンを押して、「Highlight updates when components render.」に✅チェックを入れます。

そして、カウンターなどのボタンを押して「再レンダリング」が発生すると、コンポーネント部分の外側がハイライト表示されます。

React Developer ToolsのHighlight機能にはバグがあるので注意

作成したサンプルのコードは以下のようになっています。

App.tsx
import { useState } from 'react'
import './App.css'
import CurrentDate from './CurrentDate'

function App() {
  console.log('💻 App render')
  const [count, setCount] = useState(0)
  const [date, setDate] = useState<string>('')

  return (
    <>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
        <button onClick={() => setDate(new Date().toLocaleString())}>
          現在の日時を表示
        </button>
      </div>
      <CurrentDate date={date} />
    </>
  )
}

export default App
CurrentDate.tsx
type Props = {
  date: string
}

function CurrentDate({ date }: Props) {
  console.log('🕔 CurrentDate render')

  return (
    <div>
      <h2>現在の日時: {date}</h2>
    </div>
  )
}

export default CurrentDate

React 再レンダリング確認用サンプル(修正前)

StackBlitzの右上にあるプレビューアイコンからWebページを開いてConsoleを確認してみてください。

StackBlitzの右上にあるプレビューアイコン

countボタンを押したときも「🕔 CurrentDate render」が表示されているため、無駄に再レンダリングされていることが確認できます。

React render console.log check

※ ちなみに2回連続で表示されるのはReactのStrict Modeの影響です。

これは「memo」をインポートして、CurrentDateをメモ化することで解消できます。

TSX
import { memo } from 'react'

type Props = {
  date: string
}

function CurrentDate({ date }: Props) {
  console.log('🕔 CurrentDate render')

  return (
    <div>
      <h2>現在の日時: {date}</h2>
    </div>
  )
}

export default memo(CurrentDate)

この状態で再度確認すると、countボタンを押したときに「🕔 CurrentDate render」が表示されないことが確認できます。

React memo console.log check

React Developer Toolsのハイライトのバグ

ここまで修正したら、countボタンを押下してReact Developer Toolsのハイライト表示で確認して見てください。

CurrentDateコンポーネント(現在の日時:)部分がハイライトされる「バグ」が確認できます。

CurrentDateコンポーネント(現在の日時:)部分がハイライトされる「バグ」

Consoleには「💻 App render」しか表示されていないので、本来であればCurrentDateコンポーネント(現在の日時:)部分はハイライトされないはずです。

⚛️Profilerのほうで確認しても、count押下時に、App.tsxしかレンダリングされていないことがわかります。

原因はReactではFragment (<>…</>)を使用すると、React Developer Toolsのハイライト表示が正しく表示されないバグがあるためです。

このバグは以前にReactのGitHubのIssueにも上がりましたが、現在も修正されていません。

Bug: React devtools "highlight updates when components render" and profiler output not matching when using memo #19778

Fragment (<>…</>)を<div>...</div>に修正すると正常にハイライトされます。

<>...</> 、countを押したときにCurrentDateコンポーネント(現在の日時:)部分はハイライトされないようになっていることが確認できます。

React 再レンダリング確認用サンプル(修正後)

React Developer ToolsのHighlight機能にバグがあることを知らない人は結構多いので、再レンダリングのチェックに利用する場合は注意が必要です。