Обзор
Команда React выпустила последнее обновление 9 августа.16.9версии, эта статья кратко знакомит с изменениями и моментами, на которые необходимо обратить внимание в новой версии.
Основные изменения заключаются в следующем:
- Используется в версии 16.9
componentWillMount
,componentWillReceiveProps
а такжеcomponentWillUpdate
Вы получите предупреждение от реагирования. - Предоставляется для больших приложений React
React.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 и «стоимость» рендеринга. Его цель — помочь определить части приложения, которые медленно рендерятся, и может упростить оптимизацию, например запоминание.
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], чтобы получать свежие статьи каждую неделю, ведущие к вершине жизни!