import()对代码进行分割
实现代码分割的最佳方式则是通过动态import()语法
例如:
import Demo from './Demo';
function DemoFather() {
return (
<div>
<Demo/>
</div>
);
}
React.lazy动态引入组件
React.lazy可实现动态的引入组件。
例如:
import React from 'react';
cosnt Demo = React.lazy(() => import('./Demo'));
function DemoFather() {
return (
<div>
<Demo/>
</div>
)
}
Suspense组件
Suspense用于提高拥护体验,即当页面还未完全加载成功时,使用Suspense组件提示正在加载。
例如:
import {Suspense} from 'react';
import Demo from './Demo';
function DemoFather() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<Demo/>
</Suspense>
</div>
);
}
需要注意的是React.lazy和Suspense都只是支持客户端渲染,并不支持服务端渲染,React官方推荐了Loabable Components库用于实现服务端渲染
异常捕获边界
即如果模块加载失败,则会触发一个错误,这时候则可以通过异常捕获边界(Error boundaries)技术来处理.
例如:
import {Suspense} from 'react';
import Demo from './Demo';
function DemoFather() {
return (
<MyErrorBoundary>
<div>
<Suspense fallback={<div>Loading...</div>}>
<Demo/>
</Suspense>
</div>
</MyErrorBoundary>
);
}
基于路由的代码分割
基于路由的代码分割是开发过程中使用最频繁的代码分割方式(博主之前用Vue.js就是基于路由进行分割)。
例如:
import {BrowserRouter as Router, Router, Route, Switch} from 'react-router-dom';
import React, {Suspense, lazy} from 'react';
const Home = lazy(() => import('./routes/Home'))
const Profile = lazy(() => import('./routes/Profile'))
function App() {
return (
<Router>
<Suspense fallback={<div>Loading...</div>}
<Switch>
<Route exact path="/" component={Home}/>
<Route exact path="/profile" component={Profile}/>
<Route/>
</Switch>
</Router>
)
}
命名导出
如果使用React.lazy进行导出,那么仅支持被导出的模块为export default的方式。如果需要使用命名式的导出,则被导出的模块需要使用export const = {}的方式。
例如:
export const MyComponent = function () {
....
}
export const MyComponent2 = function () {
....
}
另一模块引入&&默认导出:
export {MyComponent as default} from './MyComponents'
Context
当存在一个场景,一个组件树(即多层组件嵌套)需要访问相同的数据,此时如果用props一层层地传递显然是非常不好的!
而Context则可以用于组件间共享需要传递的值的过程。
例如:
//首先需要创建一个Context
const ThemeContext = React.createContext('default');
//组件中使用
return (
<!-- 使用ThemeContext.Provider向下传递数据 -->
<ThemeContext.Provider value="blue">
<Toolbar/>
</ThemeContext.Provider>
);
//Toolbar的子组件
//定义contextType接收Context
static contextType = ThemeContext;
render() {
//访问context
return <button theme={this.context} />
}
错误边界
在React中要想使部分UI的JavaScript错误不导致整个应用崩溃,则需要借助错误边界(需要注意的是错误边界不会捕获事件处理函数的错误,如果需要捕获事件处理函数的错误则需要使用try catch)。
如果一个class组件定义了static getDerivedStateFormError()或componentDidCatch()两个生命周期方法中的一个或两个,则该组件就会变成一个错误边界。当抛出错误后,使用getDerivedStateFromError()渲染备用UI,需要使用componentDidCatch()打印错误信息。
例如:
static getDerivedStateFromError(error) {
//更新state使下一次渲染能够显示降级UI
return {hasError: true};
}
Fragments
由于组件渲染规定必须要存在一个根元素,一般会用一个div包裹。但是如果存在多个组件嵌套,且父组件和子组件的元素有关联,此时如果子组件用div包裹,则会阻断这种元素间的关联。
例如:
function Clumn () {
return (
<div>
<td>1</td>
<td>2</td>
</div>
)
}
function Row () {
return (
<tr>
<Clumn/>
</tr>
)
}
//而此时页面渲染的结果会是 <tr><div><td>1</td><td>2</td></div></tr>
//这显然是我们不希望的结果
//所以可以借助Fragments
//正确的Clumn的写法
function Clumn () {
return (
<>
<td>1</td>
<td>2</td>
</>
)
}
如果你和我同样是一个young coder!
欢迎关注本人公众号Code center——春繁秋实,年年常茂。