组件SCU性能优化-纯组件-ref获取DOM-受控组件
React性能优化
diff 算法
这里主要理解下 React diff算法的原理,面试可能会被问到。可以先放一放后面再回头看。
列表设置key
给列表的每个子元素设置一个唯一的 key,方便元素的复用,只需调整顺序即可。
SCU优化
问题背景:修改了父组件的数据,所有的子孙组件都需要重新 render。但实际上有很多组件没必要重新 render,只有当组件的 state 和 props 发生改变时,再调用自己的 render 函数。
React 提供了一个生命周期方法 shouldComponentUpdate(简称为 SCU),可以控制 render 方法是否被调用
shouldComponentUpdate(nextProps,nextState){
if(this.props.message !== nextProps.message || this.state.counter !== nextState.counter){
return true;
}
return false;
}
但这种方法要在每个组件都写一遍 shouldComponentUpdate,太麻烦了!
React 默认帮我们实现了这个比较,只需要将 class 继承自 PureComponent。针对函数组件,可以使用 memo 高阶组件(其实就是一个函数)将函数组件包裹起来,memo 内部会比较 props 和 state 是否改变,再决定是否执行 render 函数.
ref
通常不建议在 React 里面用 JS 原生方法操作 DOM。但某些时候确实要对 DOM 做一些操作,此时可以 用 ref 来获取 DOM 元素
如何使用 ref
在 React 元素上绑定一个 ref 属性,传一个字符串(不建议使用)
<h2 ref="xxx">哈哈哈</h2>然后使用
this.refs.xxx获取
createRef(),开发中推荐使用
利用 createRef() 提前创建一个 ref 对象,然后将创建出来的对象传递到元素
constructor() { super() this.titleRef = createRef() } ... render(){ return (<h2 ref={this.titleRef}>哈哈哈</h2>) }最后使用
this.titleRef.current获取 DOM
传入一个回调函数
在对相应元素被渲染之后,回调函数被执行,并将元素传入
<h2 ref={el => {this.titleEl = el}}>哈哈哈</h2>
ref 的类型
- 当 ref 属性用于 HTML 元素时, ref 接收底层 DOM 元素作为其 current 属性;
- 当 ref 属性用于自定义类组件时,ref 对象接收组件的挂载实例作为其
current属性。但函数组件没有实例,在这种情况下取不到组件实例。
如果想要获取函数组件中某个元素的 DOM,应该使用 forwardRef 高阶函数。forwardRef 相当于对 ref 进行了一次转发,将 ref 绑定到函数组件的某个元素上。
const Home = forwardRef(function(props,ref){
return (
<div>
<h2 ref={ref}>哈哈哈</h2>
</div>
)
})
ref 的使用还是像上面 createRef() 的那种方式