惰性渲染实际上是一种渲染优化方式之一,简单来讲一个React组件,好比Drawer抽屉组件,开始是抽屉是不显示的,也就是说visible这个prop若是初始为false的话,那么在render里就return null,也就是说这个抽屉组件就不渲染,dom树中就没有对应的结构。而后当你点击一个按钮设置visible属性为true时,此时才渲染抽屉组件,而后你又点击按钮,置visible为false,此时组件隐藏,可是dom中仍然存在,这样一个过程的好处在于初始加载时能够大大减小渲染的负担,提交页面加载速度,下面就经过Antd的Drawer源码一探究竟react
其实仔细想一想就能够发现咱们只需一个变量记录该组件是否是第一次加载便可,若是是第一次加载就return null,不然就渲染组件,后续的显隐就经过display:none来切换便可,可是Drawer组件作法有区别git
首先咱们找到Drawer的代码, 查看index.ts,发现引用的是DrawerWrapper组件,直接跳到render方法查看,实际上是一个Portal组件,能够猜到Portal组件是封装了React原生的Portal用法,必须用portal由于须要把Drawer挂在body上github
return (
<Portal visible={open} forceRender={$forceRender} getContainer={getContainer} wrapperClassName={wrapperClassName} > {({ visible, afterClose, ...rest }: IChildProps) => ( // react 15,componentWillUnmount 时 Portal 返回 afterClose, visible. <Child {...props} {...rest} open={visible !== undefined ? visible : open} afterVisibleChange={afterClose !== undefined ? afterClose : props.afterVisibleChange} handler={handler} onClose={this.onClose} onHandleClick={this.onHandleClick} /> )} </Portal> ); 复制代码
这里的visible属性的open就是经过用户传入Drawer组件的visible这个prop衍生出来的,控制Portal的显示隐藏,这里并无惰性渲染的踪影,那么继续深刻Portal的代码,在开头发现Portal是rc-util里的,其实antd全部组件都是封装自rc开头的一系列组件antd
import Portal from 'rc-util/lib/PortalWrapper';
复制代码
找到PortalWrapper组件的render,真相大白app
render() {
const { children, forceRender, visible } = this.props;
let portal = null;
const childProps = {
getOpenCount: () => openCount,
getContainer: this.getContainer,
switchScrollingEffect: this.switchScrollingEffect,
};
// 省略部分代码
if (forceRender || visible || this._component) {
portal = (
<Portal getContainer={this.getContainer} ref={this.savePortal}> {children(childProps)} </Portal>
);
}
return portal;
}
复制代码
这里能够看到用了一个portal变量,初始visible为false的话,直接走最后的return portal,返回null,不渲染任何东西,而后visible一旦设为true,则走if分支,里面的关键在于ref引用 那个savePortaldom
savePortal = c => {
// Warning: don't rename _component
// https://github.com/react-component/util/pull/65#discussion_r352407916
this._component = c;
};
复制代码
这里一旦渲染组件,则保存Portal的引用到_component这个私有变量中,而后visible再次为false,则仍是走if分支,由于this._component不是null,因此达到了惰性渲染的目的优化