Команда React недавно выпустила альфа-версию React 18. Этот выпуск предназначен в основном для улучшения приложений React.并发渲染
Вы можете попробовать следующие новые функции в React 18:
- новый
ReactDOM.createRoot()
API (заменяетReactDOM.render()
) - новый
startTransition
API (для неэкстренных обновлений) - Автоматическая пакетная оптимизация для рендеринга (в основном решает проблему невозможности пакетной обработки в асинхронных обратных вызовах)
- служба поддержки
React.lazy
Новая архитектура SSR (поддерживает<Suspense>
компоненты)
Нет, эта версия только что выпущена, и многие друзья в сообществе уже хотят попробовать ее, и мне не терпится попробовать ее с большими парнями в сообществе. Заинтересованные друзья могут подписаться на мою запись, чтобы попробовать:
Установите React 18 Альфа
Чтобы опробовать React 18 Alpha в своем проекте, попробуйте следующую команду:
npm install react@alpha react-dom@alpha
# or
yarn add react@alpha react-dom@alpha
если вы используетеCreate React App
При инициализации проекта вы можете столкнуться сreact-scripts
вызванныйcould not resolve dependency
ошибка:
Could not resolve dependency:
peer react@">= 16" from react-scripts@4.0.3
Вы можете попробовать добавить--force
Для решения этой проблемы:
npm install react@alpha react-dom@alpha --force
ReactDOM.createRoot()
В версии React 18ReactDOM.createRoot()
заменяет обычную запись программыReactDOM.render()
метод.
Этот метод в основном предназначен для предотвращения сбоя вашего приложения из-за несовместимых обновлений React 18.
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
const container = document.getElementById('root');
// Create a root.
const root = ReactDOM.createRoot(container);
// Render the top component to the root.
root.render(<App />);
При обновлении до React 18, если вы также используете функцию redner в качестве записи программы, консоль распечатает журнал ошибок, чтобы напомнить вам об использовании createRoot() , и только после этого метода вы сможете использовать новые функции React 18.
Автоматическая пакетная обработка рендеринга
В React есть классический вопрос для интервью:setState
Синхронный он или асинхронный, я часто буду спрашивать во время интервью, в частности, я представил его в статье двухлетней давности:
Изучите механизм выполнения setState из практических задач.
class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}
componentDidMount() {
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1});
console.log(this.state.val);
setTimeout(() => {
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1};
console.log(this.state.val);
}, 0);
}
render() {
return null;
}
};
Например, в приведенном выше коде рассмотрим два случая:
- Предполагая, что React вообще не имеет механизма пакетной обработки, тогда выполнение setState немедленно вызовет рендеринг страницы, а порядок печати должен быть 1, 2, 3, 4.
- Предполагая, что React имеет идеальный механизм пакетной обработки, тогда весь рендеринг должен обрабатываться единообразно после выполнения всей функции, а порядок печати должен быть 0, 0, 0, 0.
Фактически, до React 18 приведенный выше код печатался в порядке 0, 0, 2, 3.
Основная причина этой проблемы в том, чтоReact
Функция события отличается от механизма пакетирования состояний в асинхронном обратном вызове. Вне асинхронного обратного вызова все рендеринги могут быть объединены в один, внутри асинхронного обратного вызова они не будут объединены и будут рендериться несколько раз.
На самом деле, в большинстве сценариев нам нужно обновить состояние в callback-функции после вызова интерфейса или выполнения каких-то других действий, и описанный выше механизм пакетирования будет очень безвкусным.
Теперь версия React 18 решает эту проблему, независимо от того, обновляете ли вы состояние в Promise, setTimeout или другом асинхронном обратном вызове, пакет будет запущен, и приведенный выше код действительно всегда будет печатать0、0、0、0
!
Разве это не здорово! Вопрос из интервью, который React помог нам устранить 😎.
Обычно с пакетной обработкой проблем нет, но она может не подходить для некоторых особых требований (например, для получения некоторого контента из DOM сразу после изменения состояния), мы можем использоватьReactDOM.flushSync()
Выход из партии:
import { flushSync } from 'react-dom'; // Note: react-dom, not react
function handleClick() {
flushSync(() => {
setCounter(c => c + 1);
});
// React has updated the DOM by now
flushSync(() => {
setFlag(f => !f);
});
// React has updated the DOM by now
}
Ricky
В этой статье (https://github.com/reactwg/react-18/discussions/21
) подробностиAutomatic batching
, если вы заинтересованы, вы можете перейти в область комментариев, чтобы обсудить вместе.
Поддержка ленивой загрузки в SSR
React.lazy
Функции позволяют обрабатывать динамически импортированные компоненты так же, как визуализацию обычных компонентов.React.lazy
Принимает функцию, которую необходимо вызвать динамическиimport()
. он должен вернутьPromise
,ДолженPromise
нужноresolve
Одинdefault export
Реагировать на компоненты.
const MonacoEditor = React.lazy(() => import('react-monaco-editor'));
React.lazy
должны сотрудничать<Suspense>
можно лучше использовать вSuspense
Рендеринг в компонентеlazy
компонент, который можно использовать во время ожидания загрузкиlazy
изящно деградировать компоненты (например, рендеринг некоторыхloading
Эффект ).fallback
Свойство принимает все, что вы хотите отобразить во время загрузки компонента.React
элемент.
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
// Displays <Spinner> until OtherComponent loads
<React.Suspense fallback={<Spinner />}>
<div>
<OtherComponent />
</div>
</React.Suspense>
);
}
существуетReact 18
Ранее режим SSR не поддерживался для использованияSuspense
компонент, а серверные компоненты в React 18 также поддерживают использование<Suspense>
сейчас: если вы завернете компонент в<Suspense>
, сервер сначалаfallback
Компоненты в потоке передаются как HTML, и как только основной компонент загружается, React отправляет новыйHTML
для замены компонента.
<Layout>
< Article />
<Suspense fallback={<Spinner />}>
<Comments />
</Suspense>
</Layout>
Например, приведенный выше код,<Article>
Компонент будет отображаться первым,<Comments>
компоненты будутfallback
заменить<Spinner>
. однажды<Comments>
После загрузки компонента React отправит его в браузер, заменив<Spinner>
компоненты.
Dan Abramov
В этой статье (https://github.com/reactwg/react-18/discussions/37
) подробно описывает этот механизм, и если вам интересно, вы можете обсудить его в области комментариев.
startTransition API
startTransition
— это новый API, добавленный в React 18, который позволяет различать非紧急
обновление статуса.
Вот, например, сейчас такая сцена: мы идемInput
Поле вводит значение, а затем необходимо предоставить некоторые данные, отфильтрованные по введенному нами значению.
Поскольку вам необходимо динамически отображать отфильтрованное значение каждый раз, вы можете сохранить входное значение вstate
, ваш код может выглядеть так:
setInputValue (input) ;
setSearchQuery (input) ;
Прежде всего, значение, введенное пользователем, должно отображаться немедленно, но отфильтрованные данные ассоциации могут не нуждаться в такой быстрой визуализации.Если мы не будем выполнять какую-либо дополнительную обработку, до React 18 все обновления будут отображаться немедленно.Если У вас много необработанных данных, поэтому каждый раз, когда вы вводите новое значение, объем вычислений, которые вам необходимо выполнить (фильтрация квалифицированных данных в соответствии с введенным значением), очень велик, поэтому после каждого пользователя может возникнуть задержка. Вход.
Поэтому в прошлом мы могли добавлять некоторые операции защиты от сотрясений, чтобы искусственно задерживать вычисление и рендеринг отфильтрованных данных.
Новый API startTransition позволяет нам помечать данные какtransitions
условие.
import { startTransition } from 'react';
// Urgent: Show what was typed
setInputValue(input);
// Mark any state updates inside as transitions
startTransition(() => {
// Transition: Show the results
setSearchQuery(input);
});
все вstartTransition
Обновления в обратном вызове считаются非紧急处理
, если есть более срочное обновление (например, пользователь вводит новое значение), указанное выше обновление будет прервано, и обновление не будет продолжаться до тех пор, пока не будут выполнены другие срочные операции.
Как же не изящнее, чем мы добиваемся стабилизации искусственного 😇
В то же время React также предоставляет намisPending
знак переходаHook
:
import { useTransition } from 'react' ;
const [ isPending , startTransition ] = useTransition ( ) ;
вы можете использовать его и некоторыеloading
Используйте анимацию в сочетании с:
{ isPending && < Spinner / > }
Ricky
В этой статье (https://github.com/reactwg/react-18/discussions/41
) подробностиstartTransition
, если вы заинтересованы, вы можете перейти в область комментариев, чтобы обсудить вместе.
План выпуска React 18
Официальное введение React 18 (https://github.com/reactwg/react-18/discussions/4
), упомянутые в двух других APIuseDeferredValue
,<SuspenseList>
еще нетreleased
, мы воспользуемся им в следующий раз, вот график выпуска React 18:
-
React 18 Alpha
Версия: доступна сейчас - Публичная бета-версия: как минимум через несколько месяцев после альфа-версии
- Релиз RC: как минимум через несколько недель после бета-релиза
- Общий релиз: как минимум через несколько недель после релиза RC
Ссылаться на
- GitHub.com/реагировать на WG/Hot…
- GitHub.com/реагировать на WG/Hot…
- GitHub.com/реагировать на WG/Hot…
- blog.bit SRC.IO/trying-vomit-…
наконец
Если в статье есть ошибки, исправьте их в комментариях, если статья вам поможет, ставьте лайк и подписывайтесь.
Эта статья была впервые опубликована в моем личном публичном аккаунте: [код Secret Garden]:Попробуйте Реагировать 18!, добро пожаловать, чтобы следовать.
Интерфейсу Douyin срочно нужны таланты. Если вы хотите присоединиться к нам, добавьте меня в WeChat и свяжитесь со мной. Кроме того, если вы хотите присоединиться к фронт-энду, интервью, финансовому менеджменту и другим группам общения, или у вас есть какие-либо другие вещи, вы также можете добавить мой личный WeChatConardLi
Общайтесь вместе.