對于 React.PureComponent 組件函數(shù)傳遞渲染情況探討
-
對于給子組件傳遞函數(shù)的時候, 方式如下
// Parent.js (class Parent extends React.Component) state = { a : 1} changeA = ()=> { this.setState({a:2}); } handle1() {} handle2=()=> {} render() { return ( <div> <button onClick={this.changeA}>Change Parent State</button> <PureChildren myfunc={this.handle1} text="handle1 no-arrow" /> <PureChildren myfunc={() => this.handle1} text="handle1 with-arrow" /> <PureChildren myfunc={this.handle2} text="handle2 no-arrow" /> <PureChildren myfunc={() => this.handle2} text="handle2 with-arrow" /> </div> ); }
-
上述代碼輸出結(jié)果
// 點擊change parent state按鈕, 修改parent組件的state, 打印結(jié)果如下 PageA render handle1 with-arrow PureChildren Render handle2 with-arrow PureChildren Render
PureComponent 引用
export default class PageB extends React.PureComponent {
// 將PureComponebt改成Component看看效果
state = {
items: [{ a: 1 }, { a: 2 }, { a: 3 }],
};
handleClick = () => {
const { items } = this.state;
// items[0].a = 3;
// items.pop();
items.splice(items.length - 1, 1);
this.setState({ items });
// this.setState({ items: [...items] });
};
render() {
console.log('Parent Rendering', this.state.items);
return (
<div>
<ul>
{this.state.items.map(i => (
// <li key={i}>{i}</li>
<li key={i.a}>{i.a}</li>
))}
</ul>
{/* <div>{this.state.item[0].a}</div> */}
<button onClick={this.handleClick}>delete</button>
</div>
);
}
}
點擊上述 delete 按鈕, 發(fā)現(xiàn)節(jié)點 li 并沒有刪除, 這是因為 PureComponent 幫助我們進行了一個簡單的 diff, 發(fā)現(xiàn) nextState.items === prevState.items 為 true, 因為 items 是引用關系, 所以如果在 PureComponent 組件下, 需要重新創(chuàng)建一個新數(shù)組
handleClick = () => {
const { items } = this.state;
items.pop();
this.setState({ items: [...items] });
};
固定空對象
export default class PageC extends React.Component {
static obj = {};
state = {
c: '3',
};
handleClick = () => {
this.setState({
c: '4',
});
};
render() {
// const obj = {}; // 對象放在這里, 每一次渲染都是一個新對象, 所以會造成PureComponent 的重新渲染
return (
<div>
<button onClick={this.handleClick}>PageC {this.state.c}</button>
<PureComponent obj={PageC.obj} />
</div>
);
}
}
點擊 PageC 按鈕的時候, 組件狀態(tài)更新, 如果使用 render 中定義的 obj, 每次傳遞給 PureComponent 組件的屬性 obj 都是一個新的對象, 所以會造成 PureComponent 的 re-render