Эта статья для тех, кто только начинает свой путь в написании больших React приложений, но все еще использует только console.log для их дебага. Мы с вами рассмотрим работу с расширением для браузера "React Developer Tools" на простом примере, который в дальнейшем вы сможете применить в своих проектах. Это расширение дает возможность просмотра дерева компонентов, их props, состояния и контекста. Также достаточно просто отловить неэффективные компоненты, которые подвергаются повторному рендерингу, посмотреть сколько на это уходит времени и построить графики для визуализации эффективности компонентов. Благодаря этой информации вы не только сможете оптимизировать ваше приложение, но и более глубоко изучить React и понять все тонкости работы с ним.

Все примеры я буду показывать в Google Chrome, но вы можете использовать любой другой браузер, где есть это расширение

Подготовка

  1. Установите расширение "React Developer Tools".

  2. Создайте учебный проект с помощью create-react-app
    Если вы будуте создавать проект с нуля, то вам нужно будет настроить генерацию Source Map

  3. Запустите проект и откройте консоль разработчика

Первые шаги

Для начала рассмотрим приложение, которое было создано в create-react-app:

Расширение добавляет 2 вкладки в консоли разработчика: Components и Profiler. Сейчас мы видим, что все приложение лежит в компоненте App, которое не имеет никаких props. Для подробного просмотра информации о компоненте в консоли, вы можете нажать на "жучка" в правом верхнем углу.

Усложняем проект

Напишем небольшое приложение в которое будем записывать тех, кто нам должен денег, и удалять, кто уже вернул.
Я намеренно напишу сначала весь мой код в одном компоненте, чтобы посмотреть, как с помощью расширения можно отследить ненужные рендеры.

Чтобы включить подсветку рендеров, необходимо нажать на шестеренку на вкладке Components и поставить галочку у "Highlight updates when components render"

Вот код "плохого" компонента:

import './App.css';
import { useState } from 'react';

function App() {
  const [name, setName] = useState('');
  const [debt, setDebt] = useState('');
  const [debtors, setDebtors] = useState([])
  return (
    <div className="app">
      <h1 className="title">Должники</h1>
      <div className="form">
        <input
          type="text"
          placeholder="Имя"
          value={name}
          onChange={(e) => { setName(e.target.value) }}/>
        <input
          type="text"
          placeholder="Долг"
          value={debt}
          onChange={(e) => { setDebt(e.target.value) }}/>
        <button
          className="addDebtor"
          onClick={() => {
            setDebtors((prevDeptors) => [...prevDeptors, { name, debt }])
            setName('');
            setDebt('');
          }}
        >
          Добавить ????
        </button>
      </div>
      <ul className="debtorList">
        {debtors.map((debtor, i) => (
          <li key={i}>
            {`${debtor.name} - ${debtor.debt}`}
            <button 
              className="delDebtor"
              onClick={() =>
                setDebtors((prevDeptors) => prevDeptors.filter((_, iDebtor) => iDebtor !== i))
              }
            >
              Вернул ????
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

Смотрим в расширении

При каждом ререндере компонент подсвечивается рамкой. И как видно из гифки, все приложение ререндерится при вводе имени, долга, добавлении и удалении:

Давайте вынесем форму ввода, и список должников в отдельные компоненты. Теперь App выглядит следующим образом:

function App() {
  const [debtors, setDebtors] = useState([])
  return (
    <div className="app">
      <h1 className="title">Должники</h1>
      <DebtorsForm setDebtors={ setDebtors } />
      <DebtorsList debtors={ debtors } setDebtors={ setDebtors } />
    </div>
  );
}

После чего поведение нашего приложения становится намного эффективнее, теперь ввод имени и долга не запускает ререндер заголовка и списка должников:

Также обратите внимание на компонент DebtorsForm в расширении. Теперь у него появился props - setDebtors и 2 состояния name и debt, которые реактивно изменяют свои значения.

Чтобы увидеть имена state, вы можете нажать на "волшебную палочку" рядом со списком hooks, либо поставить это по умолчанию в настройках

Profiller

Отображение повторных рендеров дает быстрое представление о том, как компоненты связаны, но не дает данные для анализа конкретных компонентов. Чтобы получить больше информации, давайте посмотрим на вкладку Profiller.

Для того, чтобы использовать Profiller, щелкните синий кружок в левой части экрана, чтобы начать запись, и щелкните его еще раз, когда закончите:

По графику мы можем отследить самый долгий рендеринг в нашем кейсе - добавление элемента в список должников.

Заключение

Расширение браузера React Developer Tools предоставляет вам мощный набор утилит для анализа приложения. С помощью этих инструментов вы сможете выявлять ошибки на этапе написания кода. Вы также можете изучить, как компоненты взаимодействуют друг с другом, что позволит оптимизировать их. Этот этап является важной частью процесса разработки и дает возможность исследования в разрезе всего приложения, а не только одного компонента.

Комментарии (1)


  1. Ustas4
    15.12.2021 17:02

    Для начинающих непонятно как настраивать source map. И откуда устанавливать расширение