React16:Memo组件

React16:memo组件,为函数式组件锦上添花

Posted by wang chong on April 14, 2019

Memo组件

Memo组件是一个高阶函数,它可以将函数组件转换成类似于PureCmponent组件。

我们都知道PureComponent是一个带有shouldComponentUpdate优化的组件,纯函数组件是无法写生命周期的,对于一些相应的优化无法左右,比如就是shouldComponentUpdate钩子函数优化,Memo可以提供这种方式,把纯函数组件改成带有优化的类似Pureomponent组件,让性能更好。

Memo必须显示的指定以什么样的规则执行shouldComponentUpdate,也就是说需要传入一个方法作为shouldComponentUpdate来执行。

实战-todoList

首先写一个函数组件,让其在渲染的时候打印一行文字。

import React, {memo, Component} from "react";
const Child = ({todo}) => {
    console.log("I am rendering");
    return <li>{todo}</li>
}

然后写一个todoList组件,用于渲染函数组件。

export default class TodoList extends Component {
    constructor(props){
        super(props);
        this.state = {
            todos: [
                'hello1',
                'hello2',
                'hello3']
        }
    }
    clickHandle(){
        this.setState({todos:this.state.todos.concat(['hello4'])})
    }
    render(){
        return (
            <>
                <button onClick={()=>{this.clickHandle()}}>click</button>
                <ul>
                    {this.state.todos.map((todo,index) => (
                        <Child todo={todo} key={index}/>
                    ))}
                </ul>
            </>
        )
    }
}

没有memo组件的情况下

上面代码是没有memo组件的情况,使用按钮往todos中添加一个数据,观察渲染情况。 可以发现所有的函数组件全部都渲染了,这同样也是函数组件的一个痛处。

有mome组件的情况下

memo组件需要手动指定以什么样的规则执行shouldComponentUpdat。

const areEqual = (prevProps, nextProps) => {
    if(prevProps.todo === nextProps.todo){
        return true;
    } else {
        return false;
    }
}

改造组件

const MemoComp = memo(Child,areEqual);

使用新的组件渲染。

export default class TodoList extends Component {
    constructor(props){
        super(props);
        this.state = {
            todos: [
                'hello1',
                'hello2',
                'hello3'
            ]
        }
    }
    clickHandle(){
        this.setState({todos:this.state.todos.concat(['hello4'])})
    }
    render(){
        return (
            <>
                <button onClick={()=>{this.clickHandle()}}>click</button>
                <ul>
                    {this.state.todos.map((todo,index) => (
                        <MemoComp todo={todo} key={index}/>
                    ))}
                </ul>
            </>
        )
    }
}

观察一下情况。 完美。

总结

这个组件的出现,可以说把函数式组件又推上了一个地位。