导航
导航
文章目录󰁋
  1. 一、memo
  2. 二、lazy
  3. 三、suspense
  4. 四、hooks

React新特性(memo、lazy、suspense、hooks)

react 16给我们带来的一些列重要变化

  • render/纯组件能够return任何数据结构,以及CreatePortal Api
  • 新的context api,尝试代替一部分redux的职责
  • babel<>操作符,方便用户返回数组
  • 异步渲染/时间切片(time slicing),成倍提高性能
  • componentDidCatch,错误边界,框架层面上提高用户debug的能力
  • 未来的Suspense,优雅处理异步副作用
  • 未来的hooks

一、memo

React v16.6.0出了一些新的包装函数(wrapped functions),一种用于函数组件PureComponent / shouldComponentUpdate形式的React.memo()

  • React.memo()是一个高阶函数,它与 React.PureComponent类似,但是一个函数组件而非一个类

现在有一个显示时间的组件,每一秒都会重新渲染一次,对于Child组件我们肯定不希望也跟着渲染,所有需要用到PureComponent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import React  from 'react';

export default class extends React.Component {
constructor(props){
super(props);
this.state = {
date : new Date()
}
}

componentDidMount(){
setInterval(()=>{
this.setState({
date:new Date()
})
},1000)
}

render(){
return (
<div>
<Child seconds={1}/>
<div>{this.state.date.toString()}</div>
</div>
)
}
}

PureComponent

1
2
3
4
5
6
7
8
class Child extends React.PureComponent {
render(){
console.log('I am rendering');
return (
<div>I am update every {this.props.seconds} seconds</div>
)
}
}

现在新出了一个React.memo()可以满足创建纯函数而不是一个类的需求

1
2
3
4
5
6
7
function Child({seconds}){
console.log('I am rendering');
return (
<div>I am update every {seconds} seconds</div>
)
};
export default React.memo(Child)

React.memo()可接受2个参数,第一个参数为纯函数的组件,第二个参数用于对比props控制是否刷新,与shouldComponentUpdate()功能类似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import React from "react";

function Child({seconds}){
console.log('I am rendering');
return (
<div>I am update every {seconds} seconds</div>
)
};

function areEqual(prevProps, nextProps) {
if(prevProps.seconds===nextProps.seconds){
return true
}else {
return false
}

}
export default React.memo(Child,areEqual)

二、lazy

React.lazy 用于做Code-Splitting,代码拆分。类似于按需加载,渲染的时候才加载代码

1
2
3
4
5
6
7
8
9
10
import React, {lazy} from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));

function MyComponent() {
return (
<div>
<OtherComponent />
</div>
);
}

lazy(() => import('./OtherComponent'))使用es6import()返回一个promise,类似于:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
lazy(() => new Promise(resolve =>
setTimeout(() =>
resolve(
// 模拟ES Module
{
// 模拟export default
default: function render() {
return <div>Other Component</div>
}
}
),
3000
)
));

React.lazy的提出是一种更优雅的条件渲染解决方案

这里我们引出suspense

当我们组件未渲染完成,需要loading时,可以这么写

1
2
3
4
5
6
7
8
9
10
11
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
  • 在我们的业务场景中,OtherComponent可以代表多个条件渲染组件,我们全部加载完成才取消loding
  • 只要promise没执行到resolvesuspense都会返回fallback中的loading
  • 代码简洁,loading可提升至祖先组件,易聚合。相当优雅的解决了条件渲染。

三、suspense

Suspense主要解决的就是网络IO问题。网络IO问题其实就是我们现在用Redux+saga等等一系列乱七八糟的库来解决的「副作用」问题。

调用render函数->发现有异步请求->悬停,等待异步请求结果->再渲染展示数据

  • 引入新的api,可以使得任何state更新暂停,直到条件满足时,再渲染(像async/await
  • 在网速非常快的时候,可设置,整个数据到达Dom,更新完毕以后再渲染
  • 在网速非常慢的时候,可设置,精确到单个组件的等待、以及更新,然后再渲染
  • 会给我们提供 high-level (createFetcher)和 low-level(Placeholder, Loading)的 API,可以供给业务代码和一些小组件的书写。

更多详情

四、hooks

Hooks 的目的,简而言之就是让开发者不需要再用 class 来实现组件

hooks常用api有:useStateuseEffectuseContextuseReduceruseRef

支持一下
扫一扫,支持poetries
  • 微信扫一扫
  • 支付宝扫一扫