鍍金池/ 問答/HTML/ `React.PureComponent` 導(dǎo)致組件不更新

`React.PureComponent` 導(dǎo)致組件不更新

寫輪播圖組件的時候,React.PureComponent 莫名其妙的導(dǎo)致state修改后,而組件不更新,改成Component就ok了

如下:定時器每秒執(zhí)行一次,但是ui不更新,控制臺顯示定時執(zhí)行4次后(長度是4),才會render1次

class CyclePic extends React.PureComponent{
    constructor(props){
        super(props);

        this.togglePic=this.togglePic.bind(this);
        this.stopToggle=this.stopToggle.bind(this);
        this.timer;
        this.state={
            index:0
        }
    }
    componentDidMount(){
        this.togglePic();
    }
    componentWillUnMount(){
        this.stopToggle();
    }
    togglePic(){
        this.timer=setInterval(()=>{
            console.log(111)
            this.setState((preState,currentProps)=>{
                let nextIndex=++preState.index;
                if(nextIndex>currentProps.pics.length-1){
                    nextIndex=0;
                }
                return {index:nextIndex}
            });
        },1000);
    }
    stopToggle(){
        clearInterval(this.timer);
    }
    render(){
        console.log(222);
        return <div>{this.state.index}</div>;
    }
}

clipboard.png

回答
編輯回答
失魂人

React.PureComponent  其實是重寫了SCU(shouldComponentUpdate)方法。

React.Component shouldComponentUpdate 的實現(xiàn)是直接返回true。

這就是兩者的區(qū)別。 造成這樣的情況的原因就在于shouldComponentUpdate”錯誤“地將返回值變成false了。

PureComponent 重寫的SCU其實就是shallow equal 兩個state和nextState,prop和nextProps。

從你的代碼中看,是

let nextIndex=++preState.index; 
// 等價于

let nextIndex = preState = preState.index + 1;

因此不僅僅修改了nextIndex, 同時也修改了preState.index.

你可以繼承React.Component,自己寫SCU,然后debug看一下就明白了。

希望我的回答對你有幫助。

2017年3月11日 03:17
編輯回答
維他命
 let nextIndex=++preState.index; // 改變了 preState 的值, 導(dǎo)致當(dāng)前狀態(tài)和之前狀態(tài)的 index 值相同, 所以 PureComponent 在 shouldComponentUpdate 會返回 false.

改為

 let nextIndex= preState.index + 1;
2017年6月13日 05:57