目录
扩展学习资料
React Fragments/Portals/StrictMode【糖果】
Fragments【并列元素外包裹一个伪元素】
Portals【改变组件挂载节点】
Strict Mode【严格模式,老工程中使用,提示即将失效方法】
React Concurrent Mode【大招】
不可阻断渲染/可中断的渲染
Concurrent Mode API 【react v16.13.1】不稳定
练习
探寻React新版本带来的新技能
扩展学习资料
名称 | 链接 |
concurrent-mode 文档 | Introducing Concurrent Mode (Experimental) – React |
fragment 文档 | Fragments – React |
Portal 文档 | Portals – React |
React Fragments/Portals/StrictMode【糖果】
新版带来的新功能,可以提高我们的开发体验,解决一下曾经让我们困扰的一些问题,有利于开发。
Fragments【并列元素外包裹一个伪元素】
- 通常在render方法中需要返回一堆元素。需要在并列元素外面包裹一个元素(div)。
- 导致我们每新增一个组件就会多一层div,特别是这一层包裹毫无意义,除了满足语法要求。
- 新版本React提供了Fragments组件,并不会生成多与元素。
- render() { return [] }可以返回数组 // 在列表时候可以采用数组,比较符合语义化
import React, {Component, Fragment} from 'react'
class AppWithFragment extends Component {
render() {
return (
<Fragment> // 简写<>
<div className="app-item">云</div>
<div className="app-item">云1</div>
<div className="app-item">云2</div>
</Fragment> // 简写</>
)
}
}
class AppReturnArray extends Component {
render() {
return [
<div className="app-item">云</div>,
<div className="app-item">云1</div>,
<div className="app-item">云2</div>,
]
)
}
}
class AppWithoutFragment extends Component {
render() {
return (
<div>
<div className="app-item">云</div>
<div className="app-item">云1</div>
<div className="app-item">云2</div>
</div>
)
}
}
Portals【改变组件挂载节点】
React提供了一个能让改变挂载节点的API。通常的开发中,组件会挂载在其最近的父节点上。在某些特定的需求上,需要挂载在特定的节点上。
- 之前的做法是封装成方法,而不是在render中引入。
- 既想在render中引入,又能自定义挂载节点就需要PortalsAPI。
const mountDom = document.querySelector('#other-app');
class CustomComponent extends Component {
componentDidMount() {
// 伪代码
}
render() {
return createPortal(// 将<OtherComponent />挂载到节点MountDom上
<OtherComponent />,
mountDom,
)
}
}
import React, { Component } from 'react';
import { createPortal } from 'react-dom';
export default class PortalComponent extends Component {
constructor(props) {
super(props);
const mount = document.createElement('div');
mount.id = 'mount';
this.mountNode = mount;
}
componentDidMount() {
// const mount = document.querySelector('#mount');
document.body.appendChild(this.mountNode);
}
render() {
return createPortal(
<div>
Portal Child
</div>,
this.mountNode
);
}
};
Strict Mode【严格模式,老工程中使用,提示即将失效方法】
Strict Mode提供一个可以显示潜在问题的组件。
- 检测是否使用即将废弃的生命周期函数。
- 检测是否使用string ref 和 findDOMNode 以及 老版的context api。
- 检测是否多次调用不可预测的副作用。
- 会有两次render()
class AppWithStrictMode extends Component {
constructor(props) {
super(props);
this.state = {
list: [],
};
}
render() {
return (
<StrictMode>
// render() 执行2次
<div ref="btn">提交</div>
</StrictMode>
);
}
}
React Concurrent Mode【大招】
- 一个还在实验阶段的特性;
- 目的:让React应用能够更好地响应交互并且还能根据用户设备的硬件性能和网络条件进行对应的调节。
如果说Fiber是让应用更好的更新,那Concurrent就是让应用在体验上再上一个台阶。
不可阻断渲染/可中断的渲染
Blocking Rendering
- 当前React在更新时,包括创建一个新的DOM节点或者是现有DOM节点的移动,这些过程是不能被阻断的,一旦开始执行,就会执行到完成为止。
Interruptible Rendering
- 在Cobcurrent模式下,渲染更新是可以被中断的。特别是当渲染的过程特别耗时的时候,中断渲染来响应用户的行为,会让整个应用的体验得到提升。
Concurrent Mode API 【react v16.13.1】不稳定
让用户得到更好的视觉、产品体验
- 开启Concurrent模式
- createRoot
- createBlockingRoot
- Suspense
- Suspense 【loading展示】
<Suspense fallback={<h1>Loading...</h1>}>
<div />
</Suspense>
- SuspenseList【Suspense loading展示s】
<SuspenseList revealOrder="forwards">
<Suspense fallback={<h1>Loading...</h1>}>
<div id={1} />
</Suspense>
<Suspense fallback={<h1>Loading...</h1>}>
<div id={2} />
</Suspense>
...
</SuspenseList>
-
- useTransition 【写在离开页面的位置,当用户离开/跳转页面,当前页面请求停止】
- useDeferredValue【平常一些搜索,给定时间内,不检索搜索历史;字符串输入中,检索延迟】
React 16.6之后Suspense配合React.lazy使用已经可以做客户端懒加载。服务端的懒加载,暂时还不能实现
React目前是在用Legacy Mode
Blocking Mode【预计是在v17.x】版本是可以使用部分Concurrent Mode 的API 【包括服务端渲染,包括一些批量处理】
练习
【题目1】用 React Suspence API 与 React Lazy API 构建一个动态加载的单页面应用;