React16新特性实践
1. lazy & Suspense
React 16.6将代码分割(code-splitting)带到了一个新的level。您现在可以在真正需要时加载组件,且无需安装其他依赖库。
React.lazy() 提供了动态 import 组件的能力,实现代码分割。
Suspense 作用是在等待组件时 suspend(暂停)渲染,并显示加载标识。
目前 React v16.6 中 Suspense 只支持一个场景,即使用 React.lazy() 和 <React.Suspense> 实现的动态加载组件。
举个栗子
import React, {lazy, Suspense} from 'react';
const Lazy = lazy(() => import('./LazyComponent'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Lazy />
</Suspense>
);
}
这是一个最简单的使用例子,当我初始化<App>组件时,在Lazy组件渲染之前,Suspense组件会填充一个loading...的div
当我们的实际的业务场景中可能需要等待某个接口加载完毕后,按需渲染
const Lazy = lazy(() => new Promise(resolve => {
// 伪装成接口的定时器
setTimeout(() => {
resolve(import('./LazyComponent'));
}, 3000);
}));
这时,我们的Lazy组件将会在3000ms后渲染出来
在我们的业务场景中,App可以代表多个条件渲染组件,我们全部加载完成才取消loding。
只要promise没执行到resolve,suspense都会返回fallback中的loading。
代码简洁,loading可提升至祖先组件,易聚合。相当优雅的解决了条件渲染。
2. Memo
React.memo() 只能作用在简单的函数组件上,本质是一个高阶函数,可以自动帮助组件执行shouldComponentUpdate(),但只是执行浅比较,其意义和价值有限。
const MemoizedComponent = React.memo(props => {
/* 只在 props 更改的时候才会重新渲染 */
});
3. Hooks
Hooks 要解决的是状态逻辑复用问题,且不会产生 JSX 嵌套地狱,其特性如下:
- 多个状态不会产生嵌套,依然是平铺写法;
- Hooks 可以引用其他 Hooks;
- 更容易将组件的 UI 与状态分离;
Hooks 并不是通过 Proxy 或者 getters 实现,而是通过数组实现,每次 useState 都会改变下标,如果 useState 被包裹在 condition 中,那每次执行的下标就可能对不上,导致 useState 导出的 setter 更新错数据。
function App() {
const [open, setOpen] = useState(false);
return (
<>
<Button type="primary" onClick={() => setOpen(true)}>
Open Modal
</Button>
<Modal
visible={open}
onOk={() => setOpen(false)}
onCancel={() => setOpen(false)}
/>
</>
);
}
// [TODO]hooks的使用场景很多,待补充
4. createRef
React16 规范了 Ref 的获取方式,通过 React.createRef 取得 Ref 对象。
目前在我的开发中经常用到,例如可以在单向数据流中,可以在父组件中获取子组件的props,state等等
constructor(props) {
super(props)
this.myRef = React.createRef()
}
render() {
return <div ref={this.myRef} />
}
5. Fragment
Fragment在当前开发中也很常见,例如在render函数中返回多个子组件时,我可以用Fragment将他们包裹起来
render() {
return (
<React.Fragment>
<h2>我开着邻居家的Toyota,追着日落</h2>
<h2>被父母说是最危险的地方 她都去过</h2>
</React.Fragment>
);
}
当然我们可以用更简略的方式
render() {
return (
<>
<h2>我开着邻居家的Toyota,追着日落</h2>
<h2>被父母说是最危险的地方 她都去过</h2>
</>
);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。