React開発者ツールを使用してReactコンポーネントをデバッグする方法
著者は、 Creative Commons を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。
序章
Reactアプリは拡張と拡張が迅速に行われるように作られているため、微妙なバグがコードに侵入しやすくなります。 React Developer Toolsブラウザー拡張機能は、各コンポーネントの現在の状態をより深く理解できるようにすることで、これらのバグを追跡するのに役立ちます。 React Developer Toolsは、個々のコンポーネントの現在の props 、状態、および context とともに、Reactコンポーネントツリーを探索するためのインターフェースを提供します。 React Developer Toolsを使用すると、どのコンポーネントが再レンダリングされているかを判断したり、個々のコンポーネントのレンダリングにかかる時間を示すグラフを生成したりすることもできます。 この情報を使用して、非効率的なコードを追跡したり、データ量の多いコンポーネントを最適化したりできます。
このチュートリアルは、ReactDeveloperToolsブラウザー拡張機能をインストールすることから始まります。 次に、テキストアナライザーをテストアプリケーションとして構築します。このアナライザーは、テキストのブロックを取得し、単語数、文字数、文字数などの情報を表示します。 最後に、React Developer Toolsを使用して、テキストアナライザーのコンポーネントを探索し、変化する小道具とコンテキストを追跡します。 例ではChromeブラウザを使用しますが、Firefoxのプラグインを使用することもできます。
このチュートリアルを終了すると、React Developer Toolsを使用して、Reactプロジェクトのデバッグと探索を開始できるようになります。
前提条件
-
Chrome React Developer Tools拡張機能を使用するには、 GoogleChromeWebブラウザーまたはオープンソースのChromiumWebブラウザーをダウンロードしてインストールする必要があります。 FireFoxWebブラウザ用のReactDeveloperToolsFireFoxプラグインを使用してフォローすることもできます。
-
Node.jsを実行する開発環境が必要になります。 このチュートリアルは、Node.jsバージョン10.22.0およびnpmバージョン6.14.6でテストされました。 これをmacOSまたはUbuntu18.04にインストールするには、Node.jsをインストールしてmacOSにローカル開発環境を作成する方法またはの
PPAを使用したインストール ]セクションの手順に従います。 Ubuntu18.04にNode.jsをインストールする方法。 -
Create ReactAppでセットアップされたReact開発環境。 これを設定するには、ステップ1 — Reactクラスコンポーネントの状態を管理する方法のチュートリアルの空のプロジェクトを作成します。これにより、必須ではないボイラープレートが削除されます。 このチュートリアルでは、
debug-tutorialプロジェクト名として。 -
このチュートリアルでは、Reactコンポーネントとフックを使用します。
useStateとコンテキストフック。 コンポーネントとフックについては、チュートリアル Reactでカスタムコンポーネントを作成する方法、 Reactコンポーネントのフックで状態を管理する方法、React間で状態を共有する方法で学ぶことができますContextを持つコンポーネント。 -
また、JavaScriptとHTMLの基本的な知識も必要です。これは、HTMLシリーズでWebサイトを構築する方法およびJavaScriptでコーディングする方法にあります。 CSSの基本的な知識も役立ちます。これは、 Mozilla DeveloperNetworkで見つけることができます。
ステップ1— ReactDeveloperTools拡張機能のインストール
このステップでは、ChromeにReactDeveloperToolsブラウザ拡張機能をインストールします。 Chrome JavaScriptコンソールの開発者ツールを使用して、 debug-tutorial 前提条件で作成したプロジェクト。 この手順ではChromeを使用しますが、FirefoxにアドオンとしてReactDeveloperToolsをインストールする場合の手順はほぼ同じです。
このステップを完了すると、ブラウザーにReact Developer Toolsがインストールされ、コンポーネントを名前で探索およびフィルター処理できるようになります。
React Developer Toolsは、ChromeおよびFirefoxブラウザー用のプラグインです。 拡張機能を追加すると、開発者コンソールにツールが追加されます。 拡張機能をインストールするには、ReactDeveloperToolsのChromeプラグインページにアクセスしてください。
Chromeに追加ボタンをクリックします。 次に、拡張機能の追加ボタンをクリックして、次のことを確認します。
Chromeが拡張機能をインストールし、成功メッセージと新しいアイコンがブラウザの右上隅のアドレスバーの横に表示されます。
アイコンが表示されない場合は、パズルのピースをクリックしてから、ReactDeveloperToolsの画鋲アイコンをクリックしてアイコンを追加できます。
Reactコンポーネントがないページを表示している場合、アイコンは灰色で表示されます。 ただし、Reactコンポーネントを含むページを表示している場合、アイコンは青と緑で表示されます。 アイコンをクリックすると、アプリケーションがReactの製品版を実行していることが示されます。
digitalocean.com にアクセスして、ホームページでReactの製品版が実行されていることを確認してください。
Reactを使用するWebサイトにアクセスしたので、コンソールを開いてReact開発者ツールにアクセスします。 要素を右クリックして検査するか、[表示]>[開発者]>[JavaScriptコンソール]をクリックしてツールバーを開き、コンソールを開きます。
コンソールを開くと、コンポーネントとプロファイラーの2つの新しいタブが表示されます。
コンポーネントタブには、現在のReactコンポーネントツリーが、小道具、状態、またはコンテキストとともに表示されます。 Profiler タブでは、インタラクションを記録し、コンポーネントのレンダリングを測定できます。 ステップ3でプロファイラータブを調べます。
コンポーネントタブをクリックして、現在のコンポーネントツリーを表示します。
これは本番ビルドであるため、コードは minified になり、コンポーネントにはわかりやすい名前が付けられません。
動作中のWebサイトでReactDeveloperToolsを試したので、テストアプリケーションで使用できます。 まだ始めていない場合 debug-tutorial アプリケーションはまだ、ターミナルウィンドウに移動して実行します npm start プロジェクトのルートから。
ブラウザを開いてhttp:// localhost:3000にアクセスします。
ReactDeveloperToolsのアイコンが赤と白になっていることに注意してください。 React Developer Toolsアイコンをクリックすると、ページが開発モードになっているという警告が表示されます。 まだサンプルアプリケーションで作業しているので、これは予想されます。
コンソールを開くと、の名前が表示されます App コンポーネントタブのコンポーネント。
まだ多くの情報はありませんが、次のステップでプロジェクトを構築すると、すべてのコンポーネントがナビゲート可能なツリーを形成していることがわかります。
このステップでは、ReactDeveloperTools拡張機能をChromeに追加しました。 実稼働ページと開発ページの両方でツールをアクティブ化し、簡単に debug-tutorial コンポーネントタブのプロジェクト。 次のステップでは、ReactDeveloperToolsの機能を試すために使用するテキストアナライザーを構築します。
ステップ2—リアルタイムコンポーネントの小道具とコンテキストを特定する
このステップでは、テキストのブロックを分析するための小さなアプリケーションを作成します。 アプリは、入力フィールドのテキストの単語数、文字数、および文字頻度を決定して報告します。 アプリケーションをビルドするときは、React Developer Toolsを使用して、各コンポーネントの現在の状態と小道具を調べます。 また、React Developer Toolsを使用して、深くネストされたコンポーネントの現在のコンテキストを表示します。 最後に、ツールを使用して、状態の変化に応じて再レンダリングされるコンポーネントを識別します。
このステップを完了すると、React Developer Toolsを使用して、ライブアプリケーションを探索し、コンソールステートメントやデバッガーなしで現在の小道具と状態を観察できるようになります。
まず、大量のテキストを受け取る入力コンポーネントを作成します。
を開きます App.js ファイル:
- nano src/components/App/App.js
コンポーネント内に、 div のクラスで wrapper、次に作成します:
import React from 'react';
import './App.css';
function App() {
return(
<div className="wrapper">
<label htmlFor="text">
Add Your Text Here:
<br>
<textarea
id="text"
name="text"
rows="10"
cols="100"
>
</textarea>
</label>
</div>
)
}
export default App;
これがユーザーの入力領域になります。 The htmlFor 属性はリンクします label 要素から要素へ id の text JSXを使用します。 あなたはまた与える <textarea> 成分 10 行と 100 大量のテキスト用のスペースを提供する列。
ファイルを保存して閉じます。 次に、開く App.css:
- nano src/components/App/App.css
内容を次のように置き換えて、アプリケーションにスタイルを追加します。
.wrapper {
padding: 20px;
}
.wrapper button {
background: none;
border: black solid 1px;
cursor: pointer;
margin-right: 10px;
}
.wrapper div {
margin: 20px 0;
}
ここで、パディングを追加します wrapper クラス、次に子を単純化する <button> 背景色を削除し、マージンを追加して要素を追加します。 最後に、子に小さなマージンを追加します <div> 要素。 これらのスタイルは、テキストに関する情報を表示するために作成するコンポーネントに適用されます。
ファイルを保存します。 これを行うと、ブラウザが更新され、次の入力が表示されます。
開ける App.js:
- nano src/components/App/App.js
次に、コンテキストを作成して、 <textarea> エレメント。 useStateHookを使用してデータをキャプチャします。
import React, { createContext, useState } from 'react';
import './App.css';
export const TextContext = createContext();
function App() {
const [text, setText] = useState('');
return(
<TextContext.Provider value={text}>
<div className="wrapper">
<label htmlFor="text">
Add Your Text Here:
<br>
<textarea
id="text"
name="text"
rows="10"
cols="100"
onChange={e => setText(e.target.value)}
>
</textarea>
</label>
</div>
</TextContext.Provider>
)
}
export default App;
必ずエクスポートしてください TextContext、次にコンポーネント全体を TextContext.Provider. を追加してデータをキャプチャします onChange あなたへの小道具 <textarea> エレメント。
ファイルを保存します。 ブラウザがリロードされます。 React Developer Toolsが開いていることを確認し、次のことに注意してください。 App コンポーネントに表示されるようになりましたContext.Provider 子コンポーネントとして。
デフォルトでは、コンポーネントの総称名は次のとおりです。Context—ただし、追加することで変更できます displayName 生成されたコンテキストへのプロパティ。 中身 App.js、設定した行を追加します displayName に TextContext:
import React, { createContext, useState } from 'react';
import './App.css';
export const TextContext = createContext();
TextContext.displayName = 'TextContext';
function App() {
...
}
export default App;
追加する必要はありません displayName、ただし、コンソールでコンポーネントツリーを分析するときにコンポーネントをナビゲートするのに役立ちます。 また、の値が表示されます useState サイドバーに引っ掛けます。 入力にテキストを入力すると、ReactDeveloperToolsのhooksセクションの下に更新された値が表示されます。 App 成分。
フックの総称も State、しかし、これはコンテキストほど簡単には更新できません。 useDebugValue フックがありますが、これはカスタムフックでのみ機能し、すべてのカスタムフックに推奨されるわけではありません。
この場合、 App コンポーネントはへの小道具です TextContext.Provider. クリックしてください TextContext.Provider React Developer Toolsで、 value また、状態で設定した入力値を反映します。
React Developer Toolsは、リアルタイムのプロップとコンテキスト情報を表示します。コンポーネントを追加すると、その価値は高まります。
次に、というコンポーネントを追加します TextInformation. このコンポーネントは、単語数などの特定のデータ分析を備えたコンポーネントのコンテナになります。
まず、ディレクトリを作成します。
- mkdir src/components/TextInformation
次に開きます TextInformation.js テキストエディタで。
- nano src/components/TextInformation/TextInformation.js
コンポーネント内には、次の3つの個別のコンポーネントがあります。 CharacterCount, WordCount、 と CharacterMap. これらのコンポーネントはすぐに作成できます。
The TextInformation コンポーネントはを使用します useReducer フックして、各コンポーネントの表示を切り替えます。 作成する reducer 各コンポーネントの表示値を切り替える機能と、各コンポーネントを切り替えるボタン onClick アクション:
import React, { useReducer } from 'react';
const reducer = (state, action) => {
return {
...state,
[action]: !state[action]
}
}
export default function TextInformation() {
const [tabs, toggleTabs] = useReducer(reducer, {
characterCount: true,
wordCount: true,
characterMap: true
});
return(
<div>
<button onClick={() => toggleTabs('characterCount')}>Character Count</button>
<button onClick={() => toggleTabs('wordCount')}>Word Count</button>
<button onClick={() => toggleTabs('characterMap')}>Character Map</button>
</div>
)
}
あなたの useReducer フックは、各キーをブール値にマップするオブジェクトから始まります。 レデューサー関数は、スプレッド演算子を使用して以前の値を保持し、 action パラメータ。
ファイルを保存して閉じます。 次に開きます App.js:
- nano src/components/App/App.js
新しいコンポーネントを追加します。
import React, { createContext, useState } from 'react';
import './App.css';
import TextInformation from '../TextInformation/TextInformation';
...
function App() {
const [text, setText] = useState('');
return(
<TextContext.Provider value={text}>
<div className="wrapper">
<label htmlFor="text">
Add Your Text Here:
<br>
<textarea
id="text"
name="text"
rows="10"
cols="100"
onChange={e => setText(e.target.value)}
>
</textarea>
</label>
<TextInformation />
</div>
</TextContext.Provider>
)
}
export default App;
ファイルを保存して閉じます。 これを行うと、ブラウザがリロードされ、更新されたコンポーネントが表示されます。 クリックすると TextInformation React Developer Toolsでは、ボタンをクリックするたびに値が更新されます。
コンテナコンポーネントができたので、各情報コンポーネントを作成する必要があります。 各コンポーネントは、と呼ばれる小道具を取ります show. もしも show 偽物である場合、コンポーネントは戻ります null. コンポーネントは消費します TextContext、データを分析し、結果を表示します。
開始するには、を作成します CharacterCount 成分。
まず、新しいディレクトリを作成します。
- mkdir src/components/CharacterCount
次に、開きます CharacterCount.js テキストエディタで:
- nano src/components/CharacterCount/CharacterCount.js
コンポーネント内で、を使用する関数を作成します show 小道具とディスプレイ null もしも show 偽物です:
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { TextContext } from '../App/App';
export default function CharacterCount({ show }) {
const text = useContext(TextContext);
if(!show) {
return null;
}
return(
<div>
Character Count: {text.length}
</div>
)
}
CharacterCount.proTypes = {
show: PropTypes.bool.isRequired
}
内部 CharacterCount 関数、あなたはの値を割り当てます TextContext を使用して変数に useContext 針。 次に、 <div> を使用して文字数を表示します length 方法。 最後に、 PropTypes は、弱いタイピングシステムを追加して、間違ったプロップタイプが渡されないようにするための強制を提供します。
ファイルを保存して閉じます。 開ける TextInformation.js:
- nano src/components/TextInformation/TextInformation.js
輸入 CharacterCount ボタンの後にコンポーネントを追加して、 tabs.characterCount として show 小道具:
import React, { useReducer } from 'react';
import CharacterCount from '../CharacterCount/CharacterCount';
const reducer = (state, action) => {
return {
...state,
[action]: !state[action]
}
}
export default function TextInformation() {
const [tabs, toggleTabs] = useReducer(reducer, {
characterCount: true,
wordCount: true,
characterMap: true
});
return(
<div>
<button onClick={() => toggleTabs('characterCount')}>Character Count</button>
<button onClick={() => toggleTabs('wordCount')}>Word Count</button>
<button onClick={() => toggleTabs('characterMap')}>Character Map</button>
<CharacterCount show={tabs.characterCount} />
</div>
)
}
ファイルを保存します。 ブラウザがリロードされ、ReactDeveloperToolsにコンポーネントが表示されます。 入力に単語を追加すると、コンテキストが更新されることに注意してください。 コンポーネントを切り替えると、クリックするたびに小道具が更新されます。
プロパティをクリックして値を更新することにより、小道具を手動で追加または変更することもできます。
次に、 WordCount 成分。
ディレクトリを作成します。
- mkdir src/components/WordCount
テキストエディタでファイルを開きます。
- nano src/components/WordCount/WordCount.js
次のようなコンポーネントを作成します CharacterCount、ただし、スペースで splitメソッドを使用して、長さを表示する前に単語のarrayを作成します。
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { TextContext } from '../App/App';
export default function WordCount({ show }) {
const text = useContext(TextContext);
if(!show) {
return null;
}
return(
<div>
Word Count: {text.split(' ').length}
</div>
)
}
WordCount.proTypes = {
show: PropTypes.bool.isRequired
}
ファイルを保存して閉じます。
最後に、 CharacterMap 成分。 このコンポーネントは、テキストのブロックで特定の文字が使用される頻度を示します。 次に、パッセージ内の頻度で文字を並べ替え、結果を表示します。
まず、ディレクトリを作成します。
- mkdir src/components/CharacterMap
次に、開く CharacterMap.js テキストエディタの場合:
- nano src/components/CharacterMap/CharacterMap.js
インポートして使用する TextContext コンポーネントを使用し、 show 前のコンポーネントで行ったように結果を表示するprop:
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { TextContext } from '../App/App';
export default function CharacterMap({ show }) {
const text = useContext(TextContext);
if(!show) {
return null;
}
return(
<div>
Character Map: {text.length}
</div>
)
}
CharacterMap.proTypes = {
show: PropTypes.bool.isRequired
}
このコンポーネントでは、各文字の頻度マップを作成するために、もう少し複雑な関数が必要になります。 各文字を調べて、繰り返しがあるときはいつでも値をインクリメントする必要があります。 次に、そのデータを取得して、最も頻度の高い文字がリストの一番上になるように並べ替える必要があります。
これを行うには、次の強調表示されたコードを追加します。
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { TextContext } from '../App/App';
function itemize(text){
const letters = text.split('')
.filter(l => l !== ' ')
.reduce((collection, item) => {
const letter = item.toLowerCase();
return {
...collection,
[letter]: (collection[letter] || 0) + 1
}
}, {})
return Object.entries(letters)
.sort((a, b) => b[1] - a[1]);
}
export default function CharacterMap({ show }) {
const text = useContext(TextContext);
if(!show) {
return null;
}
return(
<div>
Character Map:
{itemize(text).map(character => (
<div key={character[0]}>
{character[0]}: {character[1]}
</div>
))}
</div>
)
}
CharacterMap.proTypes = {
show: PropTypes.bool.isRequired
}
このコードでは、次の関数を作成します itemize これは、テキストを配列の文字に分割します。 split() 文字列メソッド。 次に、文字を追加し、後続の各文字のカウントをインクリメントすることにより、配列をオブジェクトに削減します。 最後に、Object.entriesとsortを使用してオブジェクトをペアの配列に変換し、最もよく使用される文字を一番上に配置します。
関数を作成したら、テキストを関数に渡します。 render メソッドと map 結果の上に文字を表示します—配列値 [0]-およびカウント-配列値 [1]-内部 <div>.
ファイルを保存して閉じます。 この関数は、次のセクションでReactDeveloperToolsのいくつかのパフォーマンス機能を探索する機会を提供します。
次に、新しいコンポーネントをに追加します TextInformation ReactDeveloperToolsの値を見てください。
開ける TextInformation.js:
- nano src/components/TextInformation/TextInformation.js
新しいコンポーネントをインポートしてレンダリングします。
import React, { useReducer } from 'react';
import CharacterCount from '../CharacterCount/CharacterCount';
import CharacterMap from '../CharacterMap/CharacterMap';
import WordCount from '../WordCount/WordCount';
const reducer = (state, action) => {
return {
...state,
[action]: !state[action]
}
}
export default function TextInformation() {
const [tabs, toggleTabs] = useReducer(reducer, {
characterCount: true,
wordCount: true,
characterMap: true
});
return(
<div>
<button onClick={() => toggleTabs('characterCount')}>Character Count</button>
<button onClick={() => toggleTabs('wordCount')}>Word Count</button>
<button onClick={() => toggleTabs('characterMap')}>Character Map</button>
<CharacterCount show={tabs.characterCount} />
<WordCount show={tabs.wordCount} />
<CharacterMap show={tabs.characterMap} />
</div>
)
}
ファイルを保存して閉じます。 これを行うと、ブラウザが更新され、データを追加すると、新しいコンポーネントに文字頻度分析が表示されます。
このセクションでは、ReactDeveloperToolsを使用してコンポーネントツリーを探索しました。 また、各コンポーネントのリアルタイムの小道具を確認する方法と、開発者ツールを使用して小道具を手動で変更する方法も学びました。 最後に、入力によるコンポーネント変更のコンテキストを確認しました。
次のセクションでは、React Developer Tools Profiler タブを使用して、レンダリング時間が長いコンポーネントを特定します。
ステップ3—インタラクション全体でのコンポーネントレンダリングの追跡
このステップでは、React Developer Toolsプロファイラーを使用して、サンプルアプリケーションを使用する際のコンポーネントのレンダリングと再レンダリングを追跡します。 flamegraphs 、またはアプリの関連する最適化指標の視覚化をナビゲートし、その情報を使用して非効率的なコンポーネントを特定し、レンダリング時間を短縮し、アプリケーションの速度を上げます。
この手順を完了すると、ユーザーインタラクション中にレンダリングされるコンポーネントを特定する方法と、非効率的なレンダリングを減らすためにコンポーネントを構成する方法がわかります。
コンポーネントが互いにどのように変化するかをすばやく確認する方法は、コンポーネントが再レンダリングされたときに強調表示を有効にすることです。 これにより、コンポーネントがデータの変化にどのように応答するかを視覚的に確認できます。
React Developer Toolsで、設定アイコンをクリックします。 歯車のように見えます:
次に、 General の下で、コンポーネントがレンダリングされたときに更新を強調表示するというオプションを選択します。
変更を加えると、ReactDeveloperToolsは再レンダリングするコンポーネントを強調表示します。 たとえば、入力を変更すると、データがルートレベルのフックに保存され、変更するたびにコンポーネントツリー全体が再レンダリングされるため、すべてのコンポーネントが再レンダリングされます。
ルートコンポーネントの周りの画面の上部を含む、コンポーネントの周りのハイライトに注意してください。
これを、ボタンの1つをクリックしてデータを切り替えたときにコンポーネントが再レンダリングされる方法と比較してください。 ボタンの1つをクリックすると、下のコンポーネントが TextInformation 再レンダリングされますが、ルートコンポーネントは再レンダリングされません。
再レンダリングを表示すると、コンポーネントがどのように関連しているかがすぐにわかりますが、特定のコンポーネントを分析するための多くのデータは得られません。 より多くの洞察を得るために、プロファイラーツールを見てみましょう。
プロファイラーツールは、各コンポーネントのレンダリングにかかる時間を正確に測定できるように設計されています。 これは、処理が遅い、または処理が激しいコンポーネントを特定するのに役立ちます。
設定を再度開き、コンポーネントがレンダリングされたときに更新を強調表示するのチェックボックスをオフにします。 次に、コンソールのProfilerタブをクリックします。
プロファイラーを使用するには、画面の左側にある青い円をクリックして記録を開始し、終了したらもう一度クリックします。
記録を停止すると、各アイテムのレンダリングにかかった時間など、コンポーネントの変更のグラフが表示されます。
コンポーネントの相対的な効率をよく理解するには、ウィキペディアのクリエイティブコモンズページに貼り付けてください。 このテキストは興味深い結果を出すのに十分な長さですが、アプリケーションをクラッシュさせるほど大きくはありません。
テキストを貼り付けた後、プロファイラーを起動し、入力に小さな変更を加えます。 コンポーネントの再レンダリングが終了したら、プロファイリングを停止します。 アプリケーションが長い再レンダリングを処理しているため、長い休止が発生します。
記録を終了すると、React Developer Toolsは、再レンダリングされたすべてのコンポーネントと、各コンポーネントの再レンダリングにかかった時間を示すフレームグラフを作成します。
この場合、「変更」という単語からキーを押すたびに再レンダリングが行われます。 さらに重要なのは、各レンダリングにかかる時間と、長い遅延が発生した理由を示していることです。 コンポーネント App, TextContext.Provider、 と TextInformation 再レンダリングには約0.2ミリ秒かかります。 しかし CharacterMap での複雑なデータ解析のため、コンポーネントの再レンダリングにはキーストロークごとに約1秒かかります itemize 関数。
ディスプレイでは、各黄色のバーは新しいキーストロークです。 各バーをクリックすると、シーケンスを一度に1つずつ再生できます。 レンダリング時間にはわずかな違いがありますが、 CharacterMap 一貫して遅い:
設定のプロファイラーセクションの下にあるプロファイリング中に各コンポーネントがレンダリングされた理由を記録するオプションを選択すると、詳細情報を取得できます。
単語数コンポーネントを切り替えてみて、変更にかかる時間に注意してください。 テキストの内容を変更していなくても、アプリケーションはまだ遅れています。
コンポーネントにカーソルを合わせると、コンポーネントが再レンダリングされた理由が含まれていることがわかります。 この場合、コンポーネントが変更された理由は、レンダリングされた親コンポーネントです。 それはの問題です CharacterMap 成分。 CharacterMap 小道具とコンテキストが変更されていない場合でも、親が変更されるたびにコストのかかる計算を実行しています。 つまり、データが前のレンダリングと同じであっても、データを再計算します。
ランク付けされたタブをクリックすると、どれだけの時間がかかるかがわかります CharacterMap 他のすべてのコンポーネントと比較した場合:
React Developer Toolsは、問題の切り分けに役立ちました。 CharacterMap コンポーネントは、親コンポーネントが変更されるたびに再レンダリングされ、コストのかかる計算を実行します。
この問題を解決する方法は複数ありますが、いずれもメモ化を介した何らかのキャッシュが含まれます。このプロセスでは、すでに計算されたデータが再計算されるのではなく記憶されます。 lodash /memoizeやmemoize-oneなどのライブラリを使用して、結果をキャッシュできます。 itemize 関数、または組み込みのReact memo関数を使用してコンポーネント全体をメモすることができます。
Reactを使用する場合 memo、関数は、小道具またはコンテキストが変更された場合にのみ再レンダリングします。 この場合、Reactを使用します memo. 一般に、データ自体はより分離されたケースであるため、最初にメモ化する必要がありますが、コンポーネント全体をメモ化する場合、React Developer Toolsにいくつかの興味深い変更があるため、このチュートリアルではそのアプローチを使用します。
開ける CharacterMap.js:
- nano src/components/CharacterMap/CharacterMap.js
輸入 memo Reactから、関数全体をに渡します memo 関数:
import React, { memo, useContext } from 'react';
import PropTypes from 'prop-types';
import { TextContext } from '../App/App';
...
function CharacterMap({ show }) {
const text = useContext(TextContext);
if(!show) {
return null;
}
return(
<div>
Character Map:
{itemize(text).map(character => (
<div key={character[0]}>
{character[0]}: {character[1]}
</div>
))}
</div>
)
}
CharacterMap.proTypes = {
show: PropTypes.bool.isRequired
}
export default memo(CharacterMap);
あなたは移動します export default コンポーネントをに渡すためにコードの最後まで行 memo エクスポートする直前。 その後、Reactは再レンダリングする前に小道具を比較します。
ファイルを保存して閉じます。 ブラウザがリロードされ、トグルすると WordCount、コンポーネントははるかに高速に更新されます。 今回、 CharacterMap 再レンダリングしません。 代わりに、React Developer Toolsで、再レンダリングが阻止されたことを示す灰色の長方形が表示されます。
ランク付けされたタブを見ると、両方が CharacterCount そしてその WordCount 再レンダリングされましたが、理由は異なります。 以来 CharacterCount はメモ化されておらず、親が変更されたために再レンダリングされました。 The WordCount 小道具が変更されたため、再レンダリングされました。 包まれても memo、それでも再レンダリングされます。
注:メモ化は役立ちますが、この場合のように、明らかなパフォーマンスの問題がある場合にのみ使用してください。 そうしないと、パフォーマンスの問題が発生する可能性があります。Reactは、再レンダリングするたびに小道具をチェックする必要があり、小さなコンポーネントで遅延が発生する可能性があります。
このステップでは、プロファイラーを使用して、再レンダリングとコンポーネントの再レンダリングを識別しました。 また、フレームグラフとランク付けされたグラフを使用して、再レンダリングが遅いコンポーネントを特定し、 memo 小道具やコンテキストに変更がない場合に再レンダリングを防ぐ機能。
結論
React Developer Toolsブラウザー拡張機能は、アプリケーション内のコンポーネントを探索するための強力なユーティリティセットを提供します。 これらのツールを使用すると、コンソールステートメントやデバッガーを使用せずに、実際のデータを使用してコンポーネントの状態を調査し、バグを特定できます。 プロファイラーを使用して、コンポーネントが相互にどのように相互作用するかを調べることもできます。これにより、アプリケーション全体でレンダリングが遅いコンポーネントを特定して最適化できます。 これらのツールは開発プロセスの重要な部分であり、静的コードとしてだけでなく、アプリケーションの一部としてコンポーネントを探索する機会を提供します。
JavaScriptのデバッグについて詳しく知りたい場合は、組み込みのデバッガーとChromeDevToolsを使用してNode.jsをデバッグする方法に関する記事を参照してください。 その他のReactチュートリアルについては、 Reactトピックページを確認するか、React.jsシリーズのコーディング方法ページに戻ってください。