[英]Prevent unnecessary re-render of React component
我有一個PureComponent可以渲染另一個組件並實現其onClick
回調:
class ColorPicker extends React.PureComponent {
render() {
console.log('ColorPicker being rendered');
const fields = this.props.colors.map((color, idx) => {
const fieldProps = {
key: `${idx}`,
color,
/*onClick: () => { // PROBLEM HERE
this.props.colorPicked(color);
}*/
};
return <ColorField { ...fieldProps}/>;
});
return (
<div className="bla-picker">
<div>{`Refresh seed: ${this.props.seed}`}</div>
{fields}
< /div>
);
}
}
此組件有一個小問題:每當重新渲染ColorPicker
,嵌套的ColorField
需要重新渲染,因為它們的onClick
屬性每次都會更改。 每當渲染組件時,使用lambda函數將創建該函數的新實例。
我通常通過將onClick
的實現移到render
方法之外來解決此問題,例如: onClick: this.handleClick
。 但是,我無法在此執行此操作,因為onClick
處理程序需要捕獲color
變量。
解決此類問題的最佳實踐是什么?
這是一個jsfiddle進行嘗試; 並作為摘要:
class ColorField extends React.PureComponent { render() { console.log('ColorField being rendered'); const divProps = { className: 'bla-field', style: { backgroundColor: this.props.color }, onClick: this.props.onClick }; return <div { ...divProps}/>; } } class ColorPicker extends React.PureComponent { render() { console.log('ColorPicker being rendered'); const fields = this.props.colors.map((color, idx) => { const fieldProps = { key: `${idx}`, color, /*onClick: () => { // PROBLEM HERE this.props.colorPicked(color); }*/ }; return <ColorField { ...fieldProps}/>; }); return ( <div className="bla-picker"> <div>{`Refresh seed: ${this.props.seed}`}</div> {fields} < /div> ); } } class Layout extends React.PureComponent { constructor(props, ctx) { super(props, ctx); this.state = { seed: 1 }; } render() { const pickerProps = { colors: ['#f00', '#0f0', '#00f'], colorPicked: (color) => { console.log(`Color picked: ${color}`); }, seed: this.state.seed }; return ( <div> <div className="bla-button" onClick = {this.btnClicked} > {'Click Me'} </div> <ColorPicker { ...pickerProps} /> </div> ); } btnClicked = () => { this.setState({ seed: this.state.seed + 1 }); }; }; ReactDOM.render( < Layout / > , document.getElementById("react") );
.bla-button { background-color: #aaa; padding: 8px; margin-bottom: 8px; } .bla-picker {} .bla-field { width: 32px; height: 32px; }
<div id="react"> </div> <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
只要onClick
仍處於注釋狀態,則種子更改時僅重新渲染ColorPicker
(請參閱console.log
輸出)。 放入onClick
之后,所有ColorField
也會重新渲染。
您可以在ColorField組件中實現shouldComponentUpdate
,例如:
class ColorField extends React.Component {
shouldComponentUpdate(nextProps) {
return this.props.color !== nextProps.color;
}
render(){
const { color, onClick } = this.props;
console.log('Color re-rendered');
return (
<div
className="color"
onClick={onClick}
style={{
backgroundColor: color,
height: '50px',
width: '50px',
}}
/>
)
}
}
請注意,在第一個解決方案中,我們只能使用React.Component,因為我們自己實現了shouldComponentUpdate
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.