React последняя версия 16.9 поддерживает оценку производительности компонентов!

React.js

Обзор

Команда React выпустила последнее обновление 9 августа.16.9версии, эта статья кратко знакомит с изменениями и моментами, на которые необходимо обратить внимание в новой версии.

Основные изменения заключаются в следующем:

  • Используется в версии 16.9componentWillMount,componentWillReceivePropsа такжеcomponentWillUpdateВы получите предупреждение от реагирования.
  • Предоставляется для больших приложений ReactReact.Profilerдля оценки эффективности
  • использоватьjavascript:form URL, React выдаст предупреждение, и эта запись будет запрещена в будущей основной версии.
  • заброшенныйFactoryкомпоненты
  • для тестированияact()Методы официально поддерживают асинхронность

Небезопасный жизненный цикл

В версии 16.3 команда React обсудила потенциальные проблемы этих трех жизненных циклов, которые будут добавлены в версии 16.3.UNSAFE_Префиксы как их алиасы, по плану на тот момент, будут выдавать предупреждения в 16.9 и полностью уберутся в мажорной версии 17.0componentWillMountтри жизненных цикла.

  • КомпонентWillMount →UNSAFE_componentWillMount
  • компонентWillReceiveProps →UNSAFE_componentWillReceiveProps
  • компонентWillUpdate →UNSAFE_componentWillUpdate
Что это значит для старых проектов?

На самом деле, это не имеет большого значения.Официальная гарантия заключается в том, что даже в 17.0 использоватьUNSAFE_Жизненный цикл также можно использовать в обычном режиме, но имя функции жизненного цикла изменилось. Чтобы избежать появления предупреждений при обновлении старых проектов, вы можете вручную изменить имя функции. Конечно, можно использовать и официальные инструменты.codemodЧтобы изменить одним щелчком мыши:

cd your_project
npx react-codemod rename-unsafe-lifecycles

Команда разработчиков также может добавить в проект строгий режим (Strict Mode)<React.StrictMode>запретить использование таких потенциально рискованных жизненных циклов.

Оценка производительности с помощью React.Profiler

В этом обновлении React 16.9 есть способ программно собирать измеренный код, часто используется в больших проектах React.

Его можно добавить как узел в любом месте приложения React, и он может оценивать частоту рендеринга приложения React и «стоимость» рендеринга. Его цель — помочь определить части приложения, которые медленно рендерятся, и может упростить оптимизацию, например запоминание.

render(
  <App>
    <Profiler id="Navigation" onRender={callback}>
      <Navigation {...props} />
    </Profiler>
    <Main {...props} />
  </App>
);

Profiler можно использовать в нескольких местах или вкладывать. Он принимает два параметра id и onRender, onRender будет обновляться в ReactcommitЭтап, который является последним этапом внутреннего обновления, на этом этапе React реализует все обновления и возвращает их в DOM. Когда onRender запускается, он также возвращает некоторые параметры производительности этого обновления:

  • идентификатор, используемый для различения нескольких Pofilers, передаваемых реквизитами
  • фаза, значение равно "mount" или "update", указывающее, монтируется ли текущее дерево компонентов в первый раз (mount) или находится в цикле обновления (update)
  • factDuration, время, необходимое для обновления текущего дерева компонентов, с использованием некоторых методов кэширования компонентов, таких как React.memo, можно значительно сократить.
  • baseDuration, время первоначального монтирования дерева компонентов, можно понимать как время, затрачиваемое на рендеринг без какой-либо оптимизации.
  • startTime, начальная временная метка этого раунда обновлений
  • commitTime, метка времени окончания этого раунда обновлений (крайний срок достижения стадии фиксации)
  • стек планирования взаимодействий обновлен в этом раунде

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

должен быть в курсеProfilerДаже если это легкий компонент, все равно будут возникать накладные расходы на производительность и вычисления, и его не рекомендуется использовать в производственной среде.

Метод act() для тестирования официально поддерживает асинхронность.

React официально предоставляет встроенную библиотеку для тестирования компонентовreact-dom/test-utils, чтобы лучше имитировать реальное поведение браузеров и пользователей в тестовой среде, а также поведение сообществабудуДля контекста официальная команда даетact()Асинхронный вызов и возможность централизованно обрабатывать изменения состояния. В предыдущих версияхact()Написание асинхронного кода (асинхронное обновление состояния) в середине вызовет следующее предупреждение.

An update to SomeComponent inside a test was not wrapped in act(...).

В React 16.9 act() также поддерживает асинхронные функции и может использоватьawait:

await act(async () => {
  // ...
});

Команда React настоятельно рекомендует предоставить тестовые примеры для ваших компонентов.В этой статьестатьяНекоторые методики тестирования и сценарии применения представлены вact(), также включает тестовые сценарии для перехватчиков, например тестирование события перехватчика:

import React, { useState } from "react";

export default function Toggle(props) {
  const [state, setState] = useState(false);
  return (
    <button
      onClick={() => {
        setState(previousState => !previousState);
        props.onChange(!state);
      }}
      data-testid="toggle"
    >
      {state === true ? "Turn off" : "Turn on"}
    </button>
  );
}

Тестовый случай выглядит следующим образом

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";

import Toggle from "./toggle";

let container = null;
beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  // container *must* be attached to document so events work correctly.
  document.body.appendChild(container);
});

afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});

it("changes value when clicked", () => {
  const onChange = jest.fn();
  act(() => {
    render(<Toggle onChange={onChange} />, container);
  });

  // get a hold of the button element, and trigger some clicks on it
  const button = document.querySelector("[data-testid=toggle]");
  expect(button.innerHTML).toBe("Turn off");

  act(() => {
    button.dispatchEvent(new MouseEvent("click", { bubbles: true }));
  });

  expect(onChange).toHaveBeenCalledTimes(1);
  expect(button.innerHTML).toBe("Turn on");

  act(() => {
    for (let i = 0; i < 5; i++) {
      button.dispatchEvent(new MouseEvent("click", { bubbles: true }));
    }
  });

  expect(onChange).toHaveBeenCalledTimes(6);
  expect(button.innerHTML).toBe("Turn on");
});

В этих примерах используется собственный API DOM, но вы также можете использоватьReact Testing Libraryдля сокращения шаблонного кода. Многие из его методов были реализованы через act().

Устареть небезопасные URL-адреса формы javascript:

Если href тега написан на javascript:, React выдаст предупреждение, если вы продолжите использовать этот способ записи в версии 16.9.

const userProfile = {
  website: "javascript: alert('you got hacked')",
};
// This will now warn:
<a href={userProfile.website}>Profile</a>

и запись будетвыдаст ошибку в будущем основном выпуске, то есть будетзапретитьЭтот тип письма подвержен уязвимостям безопасности.

Устаревший заводской компонент

Прежде чем Babel стал основным инструментом компиляции для класса JavaScript, вы можете использовать «заводскую» нотацию в React для создания компонента, который использует метод рендеринга для возврата объекта.

function FactoryComponent() {
  return { render() { return <div />; } }
}

Этот подход сбивает с толку, потому что он выглядит как функциональный компонент, но это не так. Поддержка React сделает библиотеку больше и медленнее. Таким образом, этот режим устарел в версии 16.9, и при его обнаружении выводится предупреждение. Если проект зависит от этого компонента, его можно сделать совместимым, добавив FactoryComponent.prototype=React.Component.prototype.

changlog

React

  • Предоставляет API для программной оценки производительности. (@bvaughn в #15172)

  • Удалите нестабильный_ConcurrentMode в пользу нестабильного_createRoot. (@acdlite в #15532)

React DOM

  • Устареть старые методы жизненного цикла, начинающиеся с UNSAFE_*. (@bvaughn в #15186 и @threepointone в #16103)

  • URL-адреса формы javascript: устарели. (@sebmarkbage в #15047)

  • Устаревшие компоненты «шаблона модуля» (фабрики), которые обычно не используются. (@sebmarkbage в #15145)

  • Добавлена ​​поддержка свойства disablePictureInPicture для видеокомпонента. (@eek в #15334)

  • Добавьте поддержку события onLoad для встраивания. (@чернявский в #15614)

  • Обеспечивает поддержку редактирования состояния useState в DevTools. (@bvaughn в #14906)

  • Обеспечивает поддержку переключения приостановки в DevTools. (@gaearon в #15232)

  • Предупреждать, когда setState вызывается в цикле в useEffect. (@gaearon в #15180)

  • Исправить утечку памяти. (@paulshen в #16115)

  • Исправлен сбой при использовании findDOMNode в компонентах, обернутых Suspense. (@acdlite в #15312)

  • Исправлен случай отложенного эффекта из-за слишком позднего обновления. (@acdlite в #15650)

  • Исправлен неправильный порядок параметров в предупреждающем сообщении. (@brickspert в #15345)

  • Исправление, чтобы скрыть узел перехода на более раннюю версию приостановки, когда присутствует стиль !important. (@acdlite в #15861 и #15882)

  • Улучшить показатели гидратации. (@bmeurer в #15998)

React DOM Server

  • Исправлен неправильный вывод имен пользовательских свойств CSS в стиле camelCase. (@bedakb в #16167)

  • React Test Utilities and Test Renderer

  • Добавьте act(async()=>...) для проверки асинхронных обновлений состояния. (@threepointone в #14853)

  • Добавьте поддержку вложенных актов в разных рендерерах. (@threepointone в #16039 и #16042)

  • В строгом режиме выдается предупреждение, если побочная функция вызывается вне действия. (@threepointone в #15763 и #16041)

  • Предупреждать, когда действие используется не в том средстве визуализации. (@threepointone в #15756)


Подпишитесь на официальный аккаунт [IVWEB Community], чтобы получать свежие статьи каждую неделю, ведущие к вершине жизни!