Я написал один раньшеСтатья об асинхронных компонентах Vue, я недавно хотел использовать асинхронные компоненты React, когда работал над простым проектом, поэтому вкратце понял, как его использовать, и сделал заметки здесь.
Традиционные асинхронные компоненты React в основном реализуются сами по себе.Напишите специальную функцию загрузки компонентов React в качестве инструмента реализации для асинхронных компонентов.import()
Динамический импорт для достижения асинхронной загрузки, вы можете обратиться к[Перевод] Асинхронная загрузка компонентов на основе Create React App Routing 4.0 (разделение кода)Эта статья. Если вы сделаете это, вам все равно придется писать отдельный загрузочный компонент самостоятельно, что немного хлопотно. Поэтому я хотел найти более простой способ, но я не ожидал его найти:Async React using React Router & Suspense, в этой статье описывается, как быстро реализовать загрузку асинхронных компонентов по запросу на основе новых функций React Router 4 и React.
23 октября 2018 года React выпустилверсия v16.6, в новой версии есть новая функция, которая называетсяlazy
,пройти черезlazyС компонентами Suspense мы можем реализовать асинхронные компоненты, если вы используете React v16.6 и выше:
Самый простой способ реализации:
// codes from https://react.docschina.org
import React, { lazy, Suspense } from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
);
}
Импортировано из Реактаlazy
Методы иSuspense
компонент, а затем использовать ленивый метод для обработки нашего компонента, ленивый вернет новый компонент React, который мы можем использовать непосредственно внутри тега Suspense, так что компонент будет загружаться только тогда, когда он соответствует.
lazy принимает функцию в качестве параметра, который используется внутри функцииimport()
Метод загружает компонент асинхронно, и загруженный результат возвращается.
Компоненты подвескиfallback
Свойство является обязательным, оно принимает компонент и отображается, когда внутренний асинхронный компонент не загружен, поэтому мы обычно передаемLoading
Компонент его отдает, если не передать, то сообщит об ошибке.
Итак, при использовании React Router 4 мы можем написать:
import React, { lazy, Suspense } from 'react';
import { HashRouter, Route, Switch } from 'react-router-dom';
const Index = lazy(() => import('components/Index'));
const List = lazy(() => import('components/List'));
class App extends React.Component {
render() {
return <div>
<HashRouter>
<Suspense fallback={Loading}>
<Switch>
<Route path="/index" exact component={Index}/>
<Route path="/list" exact component={List}/>
</Switch>
</Suspense>
</HashRouter>
</div>
}
}
function Loading() {
return <div>
Loading...
</div>
}
export default App;
В некоторых версиях React есть ошибка в ленивой функции, из-за которой свойство компонента React Router сообщает об ошибке, когда ленивая функция возвращает результат:React.lazy makes Route's proptypes fail.
Я столкнулся с этой ошибкой, зависящей от конкретной версии, следующим образом:
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-router-dom": "^4.3.1"
После установки зависимостей в первый раз они ни разу не обновлялись, поэтому минорная версия также должна быть минорной версией выше, а обновления нет.
Обходной путь может заключаться в том, чтобы поместить результат lazy в возвращаемый результат функции:
import React, { lazy, Suspense } from 'react';
import { HashRouter, Route, Switch } from 'react-router-dom';
const Index = lazy(() => import('components/Index'));
const List = lazy(() => import('components/List'));
class App extends React.Component {
render() {
return <div>
<HashRouter>
<Suspense fallback={Loading}>
<Switch>
<Route path="/index" exact component={props => <Index {...props}/>}/>
<Route path="/list" exact component={props => <List {...props}/>}/>
</Switch>
</Suspense>
</HashRouter>
</div>
}
}
function Loading() {
return <div>
Loading...
</div>
}
export default App;
Единственная разница между приведенным выше кодом и предыдущим заключается в том, что компонент, возвращаемый lazy, заворачивается в анонимную функцию и передается в свойство компонента компонента Route.
Таким образом, наши компоненты начнут загружаться только тогда, когда маршрут совпадет, а Webpack также автоматически разделит код на множество мелких частей, сократив время загрузки домашней страницы и размер одного js-файла. Это было отработано на работе, и это действительно легко использовать:
Если вы не используете React v16.6 или новее, вы также можете реализовать его самостоятельно, написав функцию, предназначенную для асинхронной загрузки:
function asyncComponent(importComponent) {
class AsyncComponent extends React.Component {
render() {
return this.state.component;
}
state = {
component: null
}
async componentDidMount() {
const { default: Component } = await importComponent();
this.setState({
component: <Component {...this.props}/>
});
}
}
return AsyncComponent;
}
метод, используемый сReact.lazy
Точно так же вы можете передать асинхронно загружаемую функцию.В приведенной выше функции необходимо обратить внимание наimport()
Входящий компонент заворачивается в атрибут по умолчанию, который используется при структурированииconst { default: Component } = ...
эта форма.
Эффект следующий:
В основном:
- Новая версия React проще в использовании~
- Асинхронные компоненты загружаются по запросу.Эти операции основаны на характеристиках инструментов упаковки, таких как Webpack
import
~