![](/img/trans.png)
[英]React shouldComponentUpdate() = false not stopping re-render
[英]skip re-render using shouldComponentUpdate and nextState
我目前有一个下拉select
可以在“应用”之后过滤一些图表。 它工作正常。(见下面的截图)。
The problem is that when another timespan gets selected, React does a re-render to all charts before I click 'Apply' button.
我想通过实现shouldComponentUpdate
来避免这种不必要的重新渲染,但我不知道如何。
在我尝试过的下面,但它没有用(仍然是重新渲染):
shouldComponentUpdate(nextState) { if (this.state.timespanState !== nextState.timespanState) { return true; } return false; }
但它总是返回true
,因为nextState.timespanState
是undefined
。 为什么?
下拉选择
<Select value={this.state.timespanState} onChange={this.handleTimeSpanChange}>
handleTimeSpanChange = (event) => { this.setState({ timespanState: event.target.value }); };
constructor(props) { super(props); this.state = { timespanState: 'Today'}; this.handleTimeSpanChange = this.handleTimeSpanChange.bind(this); }
您使用shouldComponentUpdate
是正确的,只是第一个参数是nextProps
,第二个参数是nextState
,因此在您的情况下, undefined
值实际上是nextProps
名称错误。
将您的代码更改为此,
shouldComponentUpdate(nextProps,nextState) { // <-- tweak this line
if (this.state.timespanState !== nextState.timespanState) {
return true;
}
return false;
}
最后,我通过将下拉选择框和图表分成两个独立的组件来解决这个问题,并将下拉组件作为其父组件图表组件的子组件。 原因是下面的说法
每当 React 组件的 state 或 props 发生变化时,它们都会自动重新渲染。
因此,React 将重新渲染该组件的 render() 方法中的所有内容。 因此,将它们放在两个单独的组件中将使它们重新渲染而不会产生副作用。 在我的情况下,过滤器组件中下拉或其他状态的任何状态更改只会导致该组件内的重新渲染。 然后使用回调函数将更新的状态传递给图表组件。
像下面这样:
子组件
export class Filter extends Component { handleApplyChanges = () => { this.props.renderPieChart(data); } render(){ return ( ... <Button onClick={this.handleApplyChanges} /> ); } }
父组件
export class Charts extends Component{ constructor(props){ this.state = { dataForPieChart: []}; this.renderPieChart = this.renderPieChart.bind(this); } renderPieChart = (data) => { this.setState({ dataForPieChart: data }); } render(){ return ( <Filter renderPieChart={this.renderPieChart} /> <Chart> ...data={this.state.dataForPieChart} </Chart> ); } }
如果还有任何问题、分歧或建议,请告诉我:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.