as

Settings
Sign out
Notifications
Alexa
Amazonアプリストア
AWS
ドキュメント
Support
Contact Us
My Cases
開発
設計と開発
公開
リファレンス
サポート

コンポーネントの再レンダリングに関する問題の調査

コンポーネントの再レンダリングに関する問題の調査

Reactで再レンダリングが行われるのは、コンポーネントの状態やプロパティの変更、一元化された状態への更新、または親コンポーネントが再レンダリングされてすべての子コンポーネントで再レンダリングがトリガーされるときです。

最新の情報をユーザーに反映するには再レンダリングが不可欠ですが、必要以上に再レンダリングを行うと、アプリのパフォーマンスとユーザーインターフェイス(UI)の滑らかさ(UIのスムーズな動きと応答性)に大きな影響を与える可能性があります。

Vegaアプリでの再レンダリングの問題の調査には、why-did-you-renderを使用できます。これは、不要な再レンダリングの特定に役立つツールです。

このページでは、Vegaアプリでの再レンダリングの問題を調査する際に、why-did-you-renderをセットアップして使用する手順について説明します。

why-did-you-renderのセットアップ

手順1: アプリプロジェクトにwhy-did-you-renderをインストールする

クリップボードにコピーしました。

npm install @welldone-software/why-did-you-render@8.0.3 --save-dev

why-did-you-renderをインストールすると、Reactコンポーネント内の不要な再レンダリングの特定に役立つ重要なデバッグツールがプロジェクトに追加され、アプリのパフォーマンスを最適化できるようになります。

コマンドを実行すると、package.jsonファイルのdevDependenciesセクションにwhy-did-you-renderパッケージが追加されて表示されます。パッケージファイルは、プロジェクトディレクトリのnode_modulesフォルダに追加されます。

手順2: アプリのbabel.config.jswhy-did-you-renderプラグインを追加する

以下の構成をアプリのbabel.config.jsに追加します。

クリップボードにコピーしました。

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],

  env: {
    development: {
      plugins: [['@babel/plugin-transform-react-jsx', { runtime: 'classic' }]],
    },
  },
}

この構成により、why-did-you-renderパッケージとの互換性が保証されます。

手順3: wdyr.tsxファイルを作成する

クリップボードにコピーしました。

/// <reference types="@welldone-software/why-did-you-render" />
import React from "react";

if (process.env.NODE_ENV === "development") {
  const whyDidYouRender = require("@welldone-software/why-did-you-render");
  whyDidYouRender(React, {
    trackAllPureComponents: true,
  });
}

wdyr.tsxファイルを作成することにより、why-did-you-renderの一元的な構成を設定し、特定の設定でのライブラリ初期化と、アプリ全体での動作制御ができるようになります。

wdyr.tsxファイルは、why-did-you-renderのトラッキング動作を構成するエントリファイルです。

trackAllPureComponents構成では、Pure React コンポーネントのトラッキングのみが可能になります。

アプリコード内のその他のコンポーネントをトラッキングするには、コンポーネントのwhyDidYouRendertrueに設定します。

例:

クリップボードにコピーしました。

const MyCustomComponent = (props) => (
  <div>
    My Custom Component
  </div>
);

MyCustomComponent.whyDidYouRender = true;

export default MyCustomComponent;

コンポーネントのトラッキングとその他のオプションについて詳しくは、why-did-you-renderのドキュメントをご覧ください。

手順4: wdtr.tsxをアプリのindex.jsにインポートする

クリップボードにコピーしました。

import './wdyr';
import { AppRegistry, LogBox } from 'react-native';
import  App  from './src/Home';
import { name as appName } from './app.json';

//その他のアプリコード

AppRegistry.registerComponent(appName, () => App);

wdtr.tsxをアプリのindex.jsファイルにインポートすると、why-did-you-renderがフックを適切に設定し、アプリ全体のコンポーネントレンダリングをトラッキングできるようになります。

手順5: アプリをデバッグモードで実行し、why-did-you-renderのログを調べる

  1. アプリをデバッグモードで実行します。手順については、Vega Studioのセットアップと使用方法を参照してください。
  2. スクロールなどのアクションをアプリで実行します。
  3. アプリログに表示されるwhy-did-you-renderのログを調べます。アプリログの表示方法については、ログの表示を参照してください。
  4. 再レンダリング中のコンポーネントのレンダリングの理由を分析します。
  5. 根本的な原因を修正して、不要な再レンダリングを排除してください。

why-did-you-renderのログ出力の例

(NOBRIDGE) GROUP    SpatialNavigationVirtualizedList
(NOBRIDGE) LOG    {"SpatialNavigationVirtualizedList": [Function anonymous]} Re-rendered because of props changes:
(NOBRIDGE) GROUP      props.renderItem
(NOBRIDGE) LOG      different functions with the same name. (more info at http://bit.ly/wdyr02)
(NOBRIDGE) LOG      {"prev renderItem": [Function renderItem]} !== {"next renderItem": [Function renderItem]}
(NOBRIDGE) GROUP      Rendered by Grid
(NOBRIDGE) LOG      {"Grid": [Function Grid]} Re-rendered because of hook changes:
(NOBRIDGE) GROUP        [hook useState result]
(NOBRIDGE) LOG        different objects. (more info at http://bit.ly/wdyr3)
(NOBRIDGE) LOG        {"prev ": ""} !== {"next ": "Unnecessary State Update!"}
(NOBRIDGE) GROUP    SpatialNavigationVirtualizedList
(NOBRIDGE) LOG    {"SpatialNavigationVirtualizedList": [Function anonymous]} Re-rendered because of props changes:
(NOBRIDGE) GROUP      props.renderItem
(NOBRIDGE) LOG      different functions with the same name. (more info at http://bit.ly/wdyr02)
(NOBRIDGE) LOG      {"prev renderItem": [Function renderItem]} !== {"next renderItem": [Function renderItem]}
(NOBRIDGE) GROUP      Rendered by Grid
(NOBRIDGE) LOG      {"Grid": [Function Grid]} Re-rendered because of hook changes:
(NOBRIDGE) GROUP        [hook useState result]
(NOBRIDGE) LOG        different objects. (more info at http://bit.ly/wdyr3)
(NOBRIDGE) LOG        {"prev ": ""} !== {"next ": "Unnecessary State Update!"}
(NOBRIDGE) GROUP    SpatialNavigationVirtualizedList
(NOBRIDGE) LOG    {"SpatialNavigationVirtualizedList": [Function anonymous]} Re-rendered because of props changes:
(NOBRIDGE) GROUP      props.renderItem
(NOBRIDGE) LOG      different functions with the same name. (more info at http://bit.ly/wdyr02)
(NOBRIDGE) LOG      {"prev renderItem": [Function renderItem]} !== {"next renderItem": [Function renderItem]}
(NOBRIDGE) GROUP      Rendered by Grid
(NOBRIDGE) LOG      {"Grid": [Function Grid]} Re-rendered because of hook changes:
(NOBRIDGE) GROUP        [hook useState result]
(NOBRIDGE) LOG        different objects. (more info at http://bit.ly/wdyr3)
(NOBRIDGE) LOG        {"prev ": ""} !== {"next ": "Unnecessary State Update!"}

このログの例では、useEffectフック内で更新が行われたため、Gridコンポーネントが再レンダリングされていることがわかります。

Gridコンポーネントの再レンダリングを解決するには、useEffectフック内の不要な状態更新を削除します。

クリップボードにコピーしました。

  useEffect(() => {
    setHeaderTitle("Unnecessary State Update!");
  }, []);

Last updated: 2025年9月30日