从零开始学React-coderwhy React课程笔记(八)

152 阅读2分钟

组件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

  1. 在 React 元素上绑定一个 ref 属性,传一个字符串(不建议使用

    <h2 ref="xxx">哈哈哈</h2>
    

    然后使用 this.refs.xxx 获取

  1. createRef(),开发中推荐使用

    利用 createRef() 提前创建一个 ref 对象,然后将创建出来的对象传递到元素

    constructor() {
      super()
      this.titleRef = createRef()
    }
    ​
    ...
    ​
    render(){
      return (<h2 ref={this.titleRef}>哈哈哈</h2>)
    }
    

    最后使用 this.titleRef.current 获取 DOM

  1. 传入一个回调函数

    在对相应元素被渲染之后,回调函数被执行,并将元素传入

    <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() 的那种方式