首先看一个案例
import React, { Component } from 'react'
function Header()
{
console.log('Header被调用')
return <h2>我是Header</h2>
}
class Banner extends Component{
render(){
console.log('Banner render函数被调用')
return <h3>我是Banner组件</h3>
}
}
function ProductList(){
console.log('ProductList被调用')
return (
<ul>
<li>商品列表1</li>
<li>商品列表2</li>
<li>商品列表3</li>
<li>商品列表4</li>
</ul>
)
}
class Main extends Component{
render(){
console.log('Main render函数被调用')
return (
<div>
<Banner/>
<ProductList/>
</div>
)
}
}
function Footer(){
console.log('Footer被调用')
return <h2>我是Footer组件</h2>
}
export default class App extends Component {
constructor(props){
super(props)
this.state ={
counter:0
}
}
render() {
console.log('App render函数被调用')
return (
<div>
<h2>当前计数:{this.state.counter}</h2>
<button onClick={e=>this.increament(1)}>+1</button>
<Header/>
<Main/>
<Footer/>
</div>
)
}
increament(count){
this.setState({
counter:this.state.counter+=count
})
}
}
当我点击加一的时候,我仅仅只想让this.state里面的counter改变,
但是所有组件都重新渲染了一遍
这样是特别消耗性能的,那么有什么办法可以解决呢?这个时候就用到了PureComponent,memo 了,那么它们两个是干嘛的呢?
首先介绍一下一个函数shouldComponentUpdate,这个函数是决定要不要进行组件更新,它里面默认的是return true
然后代码应该这样写
import React, { PureComponent,memo } from 'react'
const MemoHeader = memo(function Header()
{
console.log('Header被调用')
return <h2>我是Header</h2>
})
class Banner extends PureComponent{
render(){
console.log('Banner render函数被调用')
return <h3>我是Banner组件</h3>
}
}
function ProductList(){
console.log('ProductList被调用')
return (
<ul>
<li>商品列表1</li>
<li>商品列表2</li>
<li>商品列表3</li>
<li>商品列表4</li>
</ul>
)
}
class Main extends PureComponent{
render(){
console.log('Main render函数被调用')
return (
<div>
<Banner/>
<ProductList/>
</div>
)
}
}
const MemoFooter = memo(function Footer(){
console.log('Footer被调用')
return <h2>我是Footer组件</h2>
})
export default class App extends PureComponent {
constructor(props){
super(props)
this.state ={
counter:0
}
}
render() {
console.log('App render函数被调用')
return (
<div>
<h2>当前计数:{this.state.counter}</h2>
<button onClick={e=>this.increament()}>+1</button>
<MemoHeader/>
<Main/>
<MemoFooter/>
</div>
)
}
increament(){
this.setState({
counter:this.state.counter+1
})
}
}
解释一下
PureComponent会对state,props进行浅层比较,counter从0变成1,
shouldComponentUpdate这个函数就是return true,
Banner,Main没有依赖任何的state,props,所以return false
当return true的时候组件才会重新调用
PureComponent解决类组件,memo解决函数式组件
之后再进行改变counter的值的时候,它们都不会再重新加载了
再来说一下key值这个优化diff算法
还是看一个案例
import React, { Component } from 'react'
export default class App extends Component {
constructor(props){
super(props);
this.state={
movies:['星际穿越','金刚']
}
}
render() {
const {movies} = this.state
return (
<div>
<ul>
{
movies.map((item,index)=>{
return <li key={item}>{item}</li>
})
}
</ul>
<button onClick={e=>this.addmovie()}>添加电影</button>
</div>
)
}
addmovie(){
this.setState({
movies:['功夫',...this.state.movies]
})
}
}
方式一:在最后位置插入数据
这种情况,有无key意义并不大
方式二:在前面插入数据
这种情况,在没有key的情况下,所有的li都需要进行修改
当子元素(li)拥有key时,react使用key来匹配原有树上的子元素以及最新树上的子元素:
在下面这种场景下,绑定key的元素仅仅进行位移,不需要进行任何的修改
注意:
key应该是唯一的
key不要使用随机数(随机数在下一次render时,会重新生成一个数字)
使用index作为key,对性能是没有优化的