【React解读】React.PureComponent实战篇

时间:2021-1-8 作者:admin

前言

PureComponent通过浅比较props和state来防止页面不必要的渲染,本文是实验篇,通过React例子,以实验的方式验证PureComponent一些优化以及规避方式

实验

渲染过滤

PureComponent能阻止组件进行不必要的渲染

import React, {Component, PureComponent} from 'react';
import './App.css';
class App extends Component {
  state = {
    text: 0
  }
  render() {
    console.log('父组件输出')
    return (
        <div onClick={() => {
          this.setState({
            text: this.state.text + 1
          })
        }}>
          <span>你好世界{this.state.text}</span>
          <ChildComponent/>
        </div>
    )
  }
}
class ChildComponent extends Component{
  render() {
    console.log('子组件输出')
    return (
        <div>
          <span>这是一个子组件</span>
        </div>
    )
  }
}
// 点击你好世界控制台会输出
// 父组件输出
// 子组件输出
import React, {Component, PureComponent} from 'react';
import './App.css';
class App extends Component {
  state = {
    text: 0
  }
  render() {
    console.log('父组件输出')
    return (
        <div onClick={() => {
          this.setState({
            text: this.state.text + 1
          })
        }}>
          <span>你好世界{this.state.text}</span>
          <ChildComponent/>
        </div>
    )
  }
}
class ChildComponent extends PureComponent{
  render() {
    console.log('子组件输出')
    return (
        <div>
          <span>这是一个子组件</span>
        </div>
    )
  }
}
// 点击你好世界控制台会输出
// 父组件输出

地址更新触发渲染

如果组件的props和state中存在引用地址,引用地址中属性值的改变不会触发重新渲染,引用地址的改变才会触发重新渲染

import React, {Component, PureComponent} from 'react';
import './App.css';
let valueObj = {
  value: 0
}
class App extends Component {
  state = {
    text: 0
  }
 render() {
    console.log('父组件输出')
    return (
        <div
            onClick={() => {
              valueObj.value ++
              this.setState({
                text: this.state.text + 1
              })
            }}
        >
          <span>你好世界{this.state.text}</span>
          <ChildComponent value={valueObj}/>
        </div>
    )
  }
}
class ChildComponent extends Component{
  render() {
    console.log('子组件输出'+this.props.value.value)
    return (
        <div>
          <span>这是一个子组件{this.props.value.value}</span>
        </div>
    )
  }
}
export default App;
// 点击你好世界控制台会输出
// 父组件输出
// 子组件输出1
import React, {Component, PureComponent} from 'react';
import './App.css';
let valueObj = {
  value: 0
}
class App extends Component {
  state = {
    text: 0
  }
 render() {
    console.log('父组件输出')
    return (
        <div
            onClick={() => {
              valueObj.value ++
              this.setState({
                text: this.state.text + 1
              })
            }}
        >
          <span>你好世界{this.state.text}</span>
          <ChildComponent value={valueObj}/>
        </div>
    )
  }
}
class ChildComponent extends PureComponent{
  render() {
    console.log('子组件输出'+this.props.value.value)
    return (
        <div>
          <span>这是一个子组件{this.props.value.value}</span>
        </div>
    )
  }
}
export default App;
// 点击你好世界控制台会输出
// 父组件输出
import React, {Component, PureComponent} from 'react';
import './App.css';
let valueObj = {
  value: 0
}
class App extends Component {
  state = {
    text: 0
  }
 render() {
    console.log('父组件输出')
    return (
        <div
            onClick={() => {
              valueObj = {
                value: 0
              }
              this.setState({
                text: this.state.text + 1
              })
            }}
        >
          <span>你好世界{this.state.text}</span>
          <ChildComponent value={valueObj}/>
        </div>
    )
  }
}
class ChildComponent extends PureComponent{
  render() {
    console.log('子组件输出'+this.props.value.value)
    return (
        <div>
          <span>这是一个子组件{this.props.value.value}</span>
        </div>
    )
  }
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
// 子组件输出0

避免render中声明

render函数中声明对象会导致不必要的渲染

import React, {Component, PureComponent} from 'react';
import './App.css';
let valueObj = {
  value: 0
}
class App extends Component {
  state = {
    text: 0
  }
 render() {
    console.log('父组件输出')
    return (
        <div
            onClick={() => {
              this.setState({
                text: this.state.text + 1
              })
            }}
        >
          <span>你好世界{this.state.text}</span>
          <ChildComponent value={valueObj}/>
        </div>
    )
  }
}
class ChildComponent extends PureComponent{
  render() {
    console.log('子组件输出'+this.props.value.value)
    return (
        <div>
          <span>这是一个子组件{this.props.value.value}</span>
        </div>
    )
  }
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
import React, {Component, PureComponent} from 'react';
import './App.css';
class App extends Component {
  state = {
    text: 0
  }
 render() {
    console.log('父组件输出')
    return (
        <div
            onClick={() => {
              this.setState({
                text: this.state.text + 1
              })
            }}
        >
          <span>你好世界{this.state.text}</span>
          <ChildComponent value={{value:0}}/>
        </div>
    )
  }
}
class ChildComponent extends PureComponent{
  render() {
    console.log('子组件输出'+this.props.value.value)
    return (
        <div>
          <span>这是一个子组件{this.props.value.value}</span>
        </div>
    )
  }
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
// 子组件输出0

避免匿名函数

import React, {Component, PureComponent} from 'react';
import './App.css';
class App extends Component {
    state = {
        text: 0
    }
    render() {
        console.log('父组件输出')
        return (
            <div>
                <div
                    onClick={() => {
                        this.setState({
                            text: this.state.text + 1
                        })
                    }}
                >
                    <span>你好世界{this.state.text}</span>
                </div>
                <ChildComponent onChildrenClick={(param) => {
                    console.log(param)
                }}/>
            </div>
        )
    }
}
class ChildComponent extends PureComponent {
    onClickListen = () => {
        this.props.onChildrenClick('这是参数')
    }
    render() {
        console.log('子组件输出')
        return (
            <div onClick={this.onClickListen}>
                <span>这是一个子组件</span>
            </div>
        )
    }
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
// 子组件输出
// 点击这是一个子组件控制台输出
// 这是参数
import React, {Component, PureComponent} from 'react';
import './App.css';
class App extends Component {
    state = {
        text: 0
    }
    onChildrenClickListen = (param) => {
        console.log(param)
    }
    render() {
        console.log('父组件输出')
        return (
            <div>
                <div
                    onClick={() => {
                        this.setState({
                            text: this.state.text + 1
                        })
                    }}
                >
                    <span>你好世界{this.state.text}</span>
                </div>
                <ChildComponent onChildrenClick={this.onChildrenClickListen}/>
            </div>
        )
    }
}
class ChildComponent extends PureComponent {
    onClickListen = () => {
        this.props.onChildrenClick('这是参数')
    }
    render() {
        console.log('子组件输出')
        return (
            <div onClick={this.onClickListen}>
                <span>这是一个子组件</span>
            </div>
        )
    }
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
// 点击这是一个自组件控制台输出
// 这是参数

map遇上回调函数

当render中组件时涉及map循环遍历,同时map中返回的内容需要绑定回调事件,那么将map中返回的内容单独抽离成组件可以激活筛选渲染

import React, {Component, PureComponent} from 'react';
import './App.css';
const dataArray = [1,2]
class App extends Component {
    state = {
        text: 0
    }
    onChildrenClickListen = (param) => {
        console.log(param)
    }
    render() {
        console.log('父组件输出')
        return (
            <div>
                <div
                    onClick={() => {
                        this.setState({
                            text: this.state.text + 1
                        })
                    }}
                >
                    <span>你好世界{this.state.text}</span>
                </div>
                {
                    dataArray.map((item, index) => {
                        return (
                            <ChildComponent onChildrenClick={() => {
                                this.onChildrenClickListen(item)
                            }}/>
                        )
                    })
                }
            </div>
        )
    }
}
class ChildComponent extends PureComponent {
    render() {
        console.log('子组件输出')
        return (
            <div onClick={this.props.onChildrenClick}>
                <span>这是一个子组件</span>
            </div>
        )
    }
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
// 子组件输出
// 子组件输出
// 点击第一个这是一个子组件控制台输出
// 1
import React, {Component, PureComponent} from 'react';
import './App.css';
const dataArray = [1,2]
class MyMapItem extends PureComponent {
    onChildrenClickListen = () => {
        this.props.onChildrenClickListen(this.props.item)
    }
    render(){
        return (
            <ChildComponent onChildrenClick={this.onChildrenClickListen}/>
        )
    }
}
class App extends Component {
    state = {
        text: 0
    }
    onChildrenClickListen = (param) => {
        console.log(param)
    }
    renderMap = (item, index) => {
        return <MyMapItem item={item} onChildrenClickListen={this.onChildrenClickListen}/>
    }
    render() {
        console.log('父组件输出')
        return (
            <div>
                <div
                    onClick={() => {
                        this.setState({
                            text: this.state.text + 1
                        })
                    }}
                >
                    <span>你好世界{this.state.text}</span>
                </div>
                {
                    dataArray.map(this.renderMap)
                }
            </div>
        )
    }
}
class ChildComponent extends PureComponent {
    render() {
        console.log('子组件输出')
        return (
            <div onClick={this.props.onChildrenClick}>
                <span>这是一个子组件</span>
            </div>
        )
    }
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
// 点击第一个这是一个子组件控制台输出
// 1
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。