React纯组件pureComponent、React.memo(FunComponent,compareFunction)、React.useMemo(callback,array)

目录​​​​​​​

PureComponent

简单的实现

示例

注意

React.memo(FunComponent,compareFunction)

示例

React.useMemo(callback,array)

示例


PureComponent

把继承类从 Component 换成 PureComponent 即可,可以减少不必要的 render 操作的次数,从而提高性能。

当父组件更新时,如果传入子组件的 props 和 state 都没发生改变(通过下面shallowEqual函数浅层比较),render方法就不会触发,省去 Virtual DOM 的生成和比对过程。

简单的实现

function shallowEqual(obj1, obj2) {
	if (Object.keys(obj1).length !== Object.keys(obj2).length){
		return false;
	}
    //不用for in是由于它会遍历对象原型上的属性。
    const keys = Object.keys(obj1)
	for (let key of keys) {
		if (obj1[key] !== obj2[key]) {
			return false;
		}
	}
	return true;
}

示例

下面在定时器中不断对父组件的count进行加1,传入子组件Pure和NoPure的属性虽然没有变,但不是继承于PureComponent的组件会重新触发render函数,会每隔1s重新输出1遍'Component'字符串。

import React, { Component ,PureComponent} from 'react'

class Pure extends PureComponent {
    render() {
        console.log("PureComponent")
        return (
            <div>
                标题:{this.props.title}
            </div>
        )
    }
}


class NoPure extends Component {
    render() {
        console.log("Component")
        return (
            <div>
               标题:{this.props.title}
            </div>
        )
    }
}

export default class Purememo extends Component {
    constructor(props){
        super(props)
        this.state={
            title:'shouldComponentUpdate使用',
            count:0
        }
    }
    componentDidMount(){
        setInterval(()=>{
            this.setState({
                count:this.state.count+1
            })
        },1000)
    }
    render() {
        return (
            <div>
                <p>{this.state.count}</p>
                <Pure title={this.state.title}></Title>
                <NoPure title={this.state.title}></Count>
            </div>
        )
    }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Purememo />, rootElement);

注意

在class组件内,只有那些状态和属性不经常的更新的组件才会用PureComponent进行优化,对于经常更新的,这样处理后反而浪费性能,因为每一次浅比较也是要消耗时间的。

React.memo(FunComponent,compareFunction)

和类组件中的PureComponent作用相同,用于减少不必要的 render 操作的次数。

FunComponent为函数子组件;

compareFunction为自定义的比较函数,可以不传默认比较函数组件的传入属性。该函数还默认接收2个参数,一个是改变前的属性值,和变化后的属性值,当返回为false时,组件才会重新渲染。

示例

下面在定时器中不断对父组件的count进行加1,传入子组件Child中的属性虽然没有变,会重新渲染,(打开Child组件注释)会每隔1s重新输出1遍I am rendering'字符串。而使用了React.memo后通过areEqual函数比较传入的prop属性的变化,当返回false时,该组件才会重新渲染。

import React, { component } from "react";

function Child({seconds}){
    console.log('I am rendering');
    return (
        <div>I am update every {seconds} seconds</div>
    )
};

function areEqual(prevProps, nextProps) {
    if(prevProps.seconds===nextProps.seconds){
        return true
    }else {
        return false
    }

}
const ChildMemo = React.memo(Child,areEqual)
export default class Example extends Component {
    constructor(props){
        super(props)
        this.state={
            title:'shouldComponentUpdate使用',
            count:0
        }
    }
    componentDidMount(){
        setInterval(()=>{
            this.setState({
                count:this.state.count+1
            })
        },1000)
    }
    render() {
        return (
            <div>
                <p>{this.state.count}</p>
                <ChildMemo title={this.state.title}></ChildMemo >
                {/* <Child seconds={1}></Child> */}
            </div>
        )
    }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Example />, rootElement);

 

React.useMemo(callback,array)

useMemo的返回值是一个记忆值,是callback的返回值。

  1. 不传数组,每次更新都会重新计算
  2. 空数组,只会计算一次
  3. 依赖对应的值,当对应的值发生变化时,才会重新计算(可以依赖另外一个 useMemo 返回的值)

示例

每次点击setCount,count加1。当点击更新时,由于add依赖于memoValue变量改变了,会使add重新计算,渲染新的add值。

function App () {
  const [ count, setCount ] = useState(0)
  const [ memoValue, setmemoValue ] = useState(false)
  const add = React.useMemo(() => count + 1, [memoValue])
  return (
    <div>
      点击次数: { count }
      <br/>
      次数加一: { add }
      <button onClick={() => { setCount(count + 1)}}>点我</button>
      <button onClick={() => { setmemoValue(!memoValue)}}>点我更新</button>
    </div>
    )
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值