React.PureComponent 和 forceUpdate 小结

forceUpdate()方法:

Sub.js
class Sub extends React.Component{
    construcotr(){
        super();
        this.name = "yema";
    }
    refChangeName(name){
        this.name = name;
        this.forceUpdate(); 
    }
    render(){
        return (<div>{this.name}</div>);
    }
}

App.js
class App extends React.Component{

    handleClick(){
        this.subRef.refChangeName("yemafuren");
    }
    render(){
        return (<div>
            <Sub ref={(sub)=>{this.subRef = sub;}} />
            <button onClick={this.handleClick}>click</button>
        </div>);
    }
}   复制代码


Vue中如果更改的data和上一次的data相同,vue便不会重新渲染,提高了性能。 但在react中才不管是不是相同,只要状态更新便会重新渲染,为此React提供了一个生命周期钩子函数 shouldComponentUpdate( )这个钩子函数中接收最新的propsstate但此时this上的propsstate还未更新,于是我们就可以做一下判断, 如果this.props === props && this.state === state 则return false 代表此次不必要更新。否则return true。(当我们没有写shouldComponentUpdate React底层默认return true) 


可以结合代码来理解一下

class ShouldUpdate extends Component {
     shouldComponentUpdate (props, state) {
    // isEqual 利用的是lodash工具库更新深拷贝的对比  也可以利用JOSN.stringify来转化成字符创比较 效果一样
        if ( _.isEqual(props, this.props) && _.isEqual(state, this.state)) {
            return false
        }
        return true
    }
}复制代码

PureComponent

React.PureComponentReact.Component 几乎完全相同,但 React.PureComponent 通过prop和state的浅对比来实现 shouldComponentUpate()

React.PureComponent shouldComponentUpdate() 只会对对象进行浅对比。如果对象包含复杂的数据结构,它可能会因深层的数据不一致而产生错误的否定判断(表现为对象深层的数据已改变视图却没有更新)。当你期望只拥有简单的propsstate时,才去继承 PureComponent ,或者在你知道深层的数据结构已经发生改变时使用 forceUpate() 。或者,考虑使用 不可变对象 来促进嵌套数据的快速比较。


forceUpdate( ) :来使用 强制更新 在需要强制更新的组件内使用 

component.forceUpdate(callback)
 
this.forceUpdate(callback) 来使用 强制更新 在需要强制更新的组件内使用 复制代码

默认情况,当你的组件或状态发生改变,你的组件将会重渲。若你的render()方法依赖其他数据,你可以通过调用forceUpdate()来告诉React组件需要重渲。 调用forceUpdate()将会导致组件的 render()方法被调用,并忽略shouldComponentUpdate()。这将会触发每一个子组件的生命周期方法,不覆盖子组件的shouldComponentUpdate() 方法。 若当标签改变,React仅会更新DOM。通常你应该尝试避免所有forceUpdate() 的用法并仅在render()函数里从this.propsthis.state读取数据。

 
 
import React ,{Component,PureComponent} from 'react'
 
class Son extends PureComponent {
    constructor(props){
        super(props)
        this.state = {
           style:{ width:'100px',
            height:'100px',
            background: this.props.color  // props改变 state不会更新
        }}
    }
    render(){
        return(
            <div style = {this.state.style}>
            {console.log('Son render()')}
            </div>
        )
    }
    componentWillReceiveProps(props,state){
        this.forceUpdate()    // 每次传递属性时 都会强制渲染 并忽略shouldComponentUpdate
        if ( props.color === this.props.color ) return false;
        this.setState((pre)=>{
            let newStyle = {...pre.style}
            newStyle.background = props.color
            console.log(props.color)
            return {style:newStyle}
        })
    }
}
 
class Father extends Component {
    constructor(){
        super()
        this.state = {
            color :'pink' 
        }
    }
    changeColor = (color)=>{
        this.setState({
            color:color
        })
    }
    render(){
        return(
            <>
                {console.log('Father render')}
                <button onClick = {this.changeColor.bind(null,'black')}>blcak</button>
                <button onClick = {this.changeColor.bind(null,'pink')}>pink</button>
                <button onClick = {this.changeColor.bind(null,'yellow')}>yellow</button>
                <Son color = {this.state.color}></Son>
            </> 
        )
        
    }
 
}
 
export default Father复制代码


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值