代码划分是现代Web应用开发中越来越多地使用的一种技术,它允许在需要时只加载代码片段。例如,通过基于路线的代码划分,用户可以导航到应用程序的不同路线,并且在每个路线的代码仅在首次访问时才会被加载。
React Loadable是一个由 @jamiebuilds提供的库,它可以轻松地在React中实现代码分割,并采用React的组件模型。
让我们快速谈谈如何使用 React Loadable。
安装
只需使用 npm 或 Yarn添加可重复加载的包到您的项目:
1$ npm install react-loadable
2
3# or
4$ yarn add react-loadable
使用
让我们创建一个雕刻的例子来说明可加载的简单性。
1[label components/SomeComponent.js]
2import React from 'react';
3
4function SomeComponent() {
5 return <h1>Some Component! 💣🚀👨🎤🤘</h1>;
6}
7
8export default SomeComponent;
然后让我们在我们的应用程序组件中使用它:
1[label App.js]
2import React, { Component, Fragment } from 'react';
3import SomeComponent from './components/SomeComponent';
4
5class App extends Component {
6 state = {
7 showComponent: false
8 };
9
10 handleClick = () => {
11 this.setState({
12 showComponent: true
13 });
14 };
15
16 render() {
17 if (this.state.showComponent) {
18 return <SomeComponent />;
19 } else {
20 return (
21 <Fragment>
22 <h1>Hello!</h1>
23 <button onClick={this.handleClick}>Click me!</button>
24 </Fragment>
25 );
26 }
27 }
28}
29
30export default App;
注意该组件仅在用户点击按钮后才被渲染到视图中。显然,在这样一个简单的组件中,它不会产生任何差异,但在应用程序中的更大的组件中,非微不足道,将该组件分割成代码可能是一个好主意。
让我们用 React Loadable 重构一下代码分割:
1[label App.js]
2import React, { Component, Fragment } from 'react';
3import Loadable from 'react-loadable';
4
5function Loading() {
6 return <h3>Loading...</h3>;
7}
8
9const SomeComponent = Loadable({
10 loader: () => import('./components/SomeComponent'),
11 loading: Loading
12});
13
14class App extends Component {
15 state = {
16 showComponent: false
17 };
18
19 handleClick = () => {
20 this.setState({
21 showComponent: true
22 });
23 };
24
25 render() {
26 if (this.state.showComponent) {
27 return <SomeComponent />;
28 } else {
29 return (
30 <Fragment>
31 <h1>Hello!</h1>
32 <button onClick={this.handleClick}>Click me!</button>
33 </Fragment>
34 );
35 }
36 }
37}
38
39export default App;
可加载的更高级别组件采用两个键的对象:加载
和加载
:
- loader: 期望函数返回一个承诺,以解决一个 React 组件。 动态导入使用
import()
返回一个承诺,所以我们只需要指向要加载的组件的位置。
如果你在浏览器的Devtools中查看网络选项卡,你会看到按钮时被加载的碎片。
加载延误
如果部件被快速加载,具有中间加载部件可以成为用户界面中的视觉烦恼的来源,幸运的是,Loadable提供了一个简单的解决方案,以过去延迟的形式传递给加载部件,并在某些延迟过后评估为真实:
1// ...
2
3function Loading({ pastDelay }) {
4 return pastDelay ? <h3>Loading...</h3> : null;
5}
6
7const SomeComponent = Loadable({
8 loader: () => import('./components/SomeComponent'),
9 loading: Loading
10});
11
12// ...
默认延迟是 200ms,但您可以通过将延迟配置转移到可加载的HOC来更改,例如,我们将最大延迟更改为60ms:
1function Loading({ pastDelay }) {
2 return pastDelay ? <h3>Loading...</h3> : null;
3}
4
5const SomeComponent = Loadable({
6 loader: () => import('./components/SomeComponent'),
7 loading: Loading,
8 delay: 60
9});
错误
另一个支撑被传入加载组件,错误,这使得在尝试加载组件时发生错误时很容易返回其他东西:
1function Loading({ error }) {
2 if (error) {
3 return 'oh-noes!';
4 } else {
5 return <h3>Loading...</h3>;
6 }
7}
8
9const SomeComponent = Loadable({
10 loader: () => import('./components/SomeComponent'),
11 loading: Loading
12});
基于路线的代码分割
由于 React 中的路由器在使用 React Router v4时只是组件,所以使用 React Loadable 轻松地加载不同路由器的代码。
在这里,我们将介绍一个简单的路由代码分割的例子,使用 React Loadable. 首先,请确保我们在我们的项目中也有 react-router-dom:
1$ npm install react-router-dom
2
3# or
4$ yarn add react-router-dom
在下面的示例中,我们会静态导入仪表板组件,因为它将在根路径上立即需要,我们会使用 Loadable 仅在各自路径启用时加载设置和 AddUser 组件:
1import React, { Component } from 'react';
2import Loadable from 'react-loadable';
3import { Link, Route, BrowserRouter as Router } from 'react-router-dom';
4
5import Dashboard from './components/Dashboard';
6
7function Loading({ error }) {
8 if (error) {
9 return 'Oh nooess!';
10 } else {
11 return <h3>Loading...</h3>;
12 }
13}
14
15const Settings = Loadable({
16 loader: () => import('./components/Settings'),
17 loading: Loading
18});
19
20const AddUser = Loadable({
21 loader: () => import('./components/AddUser'),
22 loading: Loading
23});
24
25class App extends Component {
26 render() {
27 return (
28 <Router>
29 <div>
30 <Link to="/">Dashboard</Link>
31 <Link to="/settings">Settings</Link>
32 <Link to="/add-user">Add User</Link>
33
34 <Route exact path="/" component={Dashboard} />
35 <Route path="/settings" component={Settings} />
36 <Route path="/add-user" component={AddUser} />
37 </div>
38 </Router>
39 );
40 }
41}
42
43export default App;
有了这一点,你应该进入代码划分的竞赛! 看看 项目的阅读以深入了解 API 以及有关服务器端渲染等先进主题的文档。