React 百思不得其解的重复渲染问题
最近在用React+React-Router4+Redux做一个后台系统,功能、页面啥的做得差不多了。然后想着做一些优化的工作,特别我发现很多重复渲染的问题让我很疑惑
比如:
有一个父组件MonitorHome,包含了两个ControlAiAlarm子组件,这两个子组件是一个组件。在父组件里dispatch了三个异步action,然后在ControlAiAlarm里面dispatch了两个异步action去获请求接口。然后就发现子组件总共执行了十次render方法,甚至十几次,实在没想明白为什么重复渲染了这么次,不知道该怎么优化
父组件MonitorHome:
class MonitorHome extends Component {
constructor(props) {
super(props)
this.timer = null
}
componentDidMount() {
const { getDataByMonth, getDataByStation, getAiListData } = this.props;
getDataByMonth({ m: 3, t: 1 });
getDataByStation({m: 30, n: 2, t: 1});
getAiListData(60);
this.timer = setTimeout(() => {
getAiListData(60);
}, 60000);
}
componentWillUnmount() {
clearInterval(this.timer)
}
render() {
return (
<div className='monitorHome-container'>
<Row>
<Col span={8}>
<ControlAiAlarm name='control' title='近半年控制器报警归类统计'/>
</Col>
<Col span={8}>
<ControlAiAlarm name='ai' title='近半年AI报警归类统计' />
</Col>
<Col span={8}>
<AlarmTimeDiff {...this.props} />
</Col>
</Row>
<Row>
<Col span={11}>
<StationAlarmDiff {...this.props} />
</Col>
<Col span={13}>
<RealTimeAlarm {...this.props} />
</Col>
</Row>
</div>
)
}
}
const mapStateToProps = state => {
const { controllerData, aiModelData, aiListData,byMonthData, byStationData } = state.alarmDataReducer
return {
controllerData,
aiModelData,
aiListData,
byMonthData,
byStationData
}
}
const mapDispatchToProps = dispatch => ({
getDataByMonth(params) {
dispatch(fetchByMonthAction(params))
},
getDataByStation(params) {
dispatch(fetchByStationAction(params))
},
getAiListData(n) {
dispatch(fetchAiDataListAction(n))
}
})
export default connect(mapStateToProps,mapDispatchToProps)(MonitorHome)
子组件ControlAiAlarm:
class ControlAiAlarm extends Component {
constructor(props) {
super(props)
this.state = {
controllerData: [],
aiModelData: [],
}
}
componentDidMount() {
const { getControllerData, getAiModelData} = this.props;
let params = { m: 6, n: 10}
getControllerData(params);
getAiModelData(params);
}
static getDerivedStateFromProps(nextProps, prevState) {
const { controllerData, aiModelData } = nextProps;
if(controllerData !== prevState.controllerData) return { controllerData };
if(aiModelData !== prevState.aiModelData) return { aiModelData };
return null;
}
getOption () {
const { controllerData, aiModelData } = this.state;
const { theStaAiData = false, name } = this.props;
const { serie: controlSeries } = controllerData;
const { serie: aiSeries } = theStaAiData || aiModelData
let arr = (name === 'control' && controlSeries) || aiSeries
// * 计算最大报警次数及其占比
let maxVal = toolUtil.getArrObjMax(arr);
let sumVal = toolUtil.getArrObjSum(arr);
arr && arr.length && arr.forEach( item => {
if(item.value === maxVal) Object.assign(item, {
label: {
show: true
},
labelLine: {
show: true
}
})
})
let perVal = maxVal && sumVal && ((maxVal / sumVal * 100).toFixed(2) + '%');
let option = {
title: {
text: `${maxVal}次`,
left: 'center',
top: '35%',
subtext: perVal,
textStyle: {
fontSize: 22,
color: '#FFFFFF'
},
subtextStyle: {
fontSize: 16,
color: '#FFFFFF',
fontFamily: 'Adobe Heiti Std',
}
},
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
series: [
{
name: '报警参数',
type: 'pie',
radius: ['50%', '80%'],
center: [
'50%', '50%'
],
label: {
normal: {// 文字长度超过3个时,换行显示
show: false,
color: '#fff',
formatter(v) {
let text = v.name
return text.length < 3 ? text : `${text.slice(0,3)} \n${text.slice(3)}`
}
},
},
labelLine: {
normal: {
show: false
}
},
data: arr,
color: ['#4bb0f4', '#f25ca2', '#f5af19', '#91eae4', '#eef5b2', '#0ce19e','#1b55e3', ],
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
}
return option;
}
render() {
console.log('看看子组件的渲染次数') // 输出了十几次
return (
<Fragment>
<div className='title title-1'>
<img src='/assets/images/circle-icon.png' alt='' />
<span>{this.props.title}</span>
</div>
<div className='detail detail-1'>
<div className='subTitle'>
<img src='/assets/images/alarm-1.png' alt='' />
<span>报警参数 top10</span>
</div>
<ReactEcharts
option={this.getOption()}
notMerge={true}
lazyUpdate={true}
style={{width: 394,height: 206}}
/>
</div>
</Fragment>
)
}
}
const mapStateToProps = state => {
const { controllerData, aiModelData } = state.alarmDataReducer
return {
controllerData,
aiModelData,
}
}
const mapDispatchToProps = dispatch => ({
getControllerData(params) {
dispatch(fetcControllerDataAction(params))
},
getAiModelData(params) {
dispatch(fetchAiModelDataAction(params))
}
})
export default connect(mapStateToProps,mapDispatchToProps)(ControlAiAlarm)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
没细看,但是优化第一条:把Component改成
PureComponent
就对了React里引起组件变化的一般不是state和Props改变之后