memo可以解决react渲染时的效率问题,react可以将数据渲染在视图中,如果数据没有变化,视图还是重新渲染。
方法一:react中有个生命函数shouldComponentUpdate可以控制组件是否重新渲染。
import React, { Component } from 'react';
import './App.css';
class Foo extends Component{
render(){
console.log('Foo render')
return null;
}
}
class App extends Component{
state = {
count:0
};
//nextProps是下次渲染用到的props
shouldComponentUpdate(nextProps,nextState){
console.log('111',nextProps);
if(nextProps.name === this.props.name){
//不会渲染
return false;
}
return true;
}
render(){
return (
<div className="app">
<p>{this.state.count}</p>
<button
onClick={()=>{this.setState({count:this.state.count+1})}}
>
Add
</button>
<Foo name="jing"></Foo>
</div>
)
}
}
export default App;
虽然App组件重新渲染了,但在它的子组件Foo中加上shouldComponentUpdate生命周期函数后,Foo组件可以通过name前后值是否发生变化来判断是否重新渲染。
也可以通过react中的PureComponent组件达到同样的效果。
import React, { Component, PureComponent} from 'react';
import './App.css';
class Foo extends PureComponent{
render(){
console.log('Foo render')
return null;
}
}
class App extends Component{
state = {
count:0
};
render(){
return (
<div className="app">
<p>{this.state.count}</p>
<button
onClick={()=>{this.setState({count:this.state.count+1})}}
>
Add
</button>
<Foo name="jing"></Foo>
</div>
)
}
}
export default App;
但是PureComponent的实现和使用场景是有局限性的,比如在state中定义一个引用类型的状态。
import React, { Component, PureComponent} from 'react';
import './App.css';
class Foo extends PureComponent{
render(){
console.log('Foo render')
//return null;
return <div>子组件person.age的值:{this.props.person.age}</div>
}
}
class App extends Component{
state = {
count:0,
person:{
age:18
}
};
render(){
const person = this.state.person;
return (
<div className="app">
<p>父组件person.age的值:{person.age}</p>
<Foo person={person}></Foo>
<button
onClick={()=>{
person.age++;
this.setState({
person
})
}}
>
Add
</button>
</div>
)
}
}
export default App;
此时Foo组件本应该重新渲染但并没有重新渲染,是因为PureComponent提供的shouldComponentUpdate发现person的句柄本身没有发生变化才拒绝重新渲染。只有传入的props第一级发生变化才会触发重新渲染。
方法3:memo
将Foo组件用react的memo包裹起来,App父组件发生变化时Foo组件没有被重新渲染。
import React, { Component, memo} from 'react';
import './App.css';
const Foo = memo(function Foo(props){
console.log('Foo reader');
return <div>子组件person.age的值:{props.person.age}</div>
})
class App extends Component{
state = {
count:0,
person:{
age:18
}
};
callback=()=>{}
render(){
const person = this.state.person;
return (
<div className="app">
<p>count的值:{this.state.count}</p>
<Foo person={person} cb={this.callback}></Foo>
<button
onClick={()=>{this.setState({
count:this.state.count+1
})}}
>
Add
</button>
</div>
)
}
}
export default App;
PureComponent为组件提供了对比算法来避免组件做无意义的渲染,减少性能开销。而无状态组件是函数式的,不能继承PureComponent,但可以用memo包裹函数式组件达到同样的效果。








网友评论