tldr;版本:家長沒有重新渲染setState後...React組件不在setState上重新渲染
我有一個儀表板視圖,呈現多個組件。加載數據的子組件工作得很好。但我有儀表板的另一部分,我打算使用相同的數據集加載同一組件的多個版本。因此,我不是爲同一個數據集創建6個API調用,而是通過父項將數據提交給孩子。此外,我正在使用路由參數來指示要查找哪家公司。
包含自己的api調用的組件工作得很好,對路由參數運行正常。這是我在父母那裏進行api調用的組件,我有這個問題。父級正在渲染,然後是子級,然後api調用完成並設置狀態,但不是重新加載。因此,當路由參數改變時,組件顯示前一次點擊的數據(基本上總是落後一個)。
我試着改變哪些反應事件將其綁定到,我已經使用映射函數,確保「this」是我想要的「this」(它是)...沒有骰子。我知道它正確地更新狀態,如果我forceUpdate()組件中顯示正確的數據(但我不能這樣做,它會強制我將forceUpdate()添加到反應更新方法,這將導致它不斷重新加載)。
任何想法??下面是一些簡裝/混淆代碼:
家長
...
class ClientDash extends Component {
constructor(props) {
super(props);
this.state = { chartOptions: {}, data1: {}, data2: {}, data3: {}, data4: {}, data5: {}, data6: {}, loaded: false };
}
loadData(clientID) {
var currYear = moment().year();
var chartData = {
labels: [(currYear-4).toString(), (currYear-3).toString(), (currYear-2).toString(), (currYear-1).toString(), currYear.toString()],
datasets: [{
type: 'bar',
label: 'Cat1',
backgroundColor: this.props.colors[0].borderColor,
borderColor: 'white',
borderWidth: 3,
data: [null, null, null, null, null]
}, {
type: 'bar',
label: 'Cat2',
backgroundColor: this.props.colors[1].borderColor,
borderColor: 'white',
borderWidth: 3,
data: [null, null, null, null, null]
}, {
type: 'bar',
label: 'Cat3',
backgroundColor: this.props.colors[2].borderColor,
borderColor: 'white',
borderWidth: 3,
data: [null, null, null, null, null]
}, {
type: 'bar',
label: 'Cat4',
backgroundColor: this.props.colors[3].borderColor,
borderColor: 'white',
borderWidth: 3,
data: [null, null, null, null, null]
}]
};
var chartOptions = {
tooltips: {
mode: 'index',
intersect: true
},
responsive: true
};
axios(apiCall)
.then(d => {
var data = d.data;
var data1 = _.clone(chartData),
data2 = _.clone(chartData),
data3 = _.clone(chartData),
data4 = _.clone(chartData),
data5 = _.clone(chartData),
data6 = _.clone(chartData);
/* some data manipulation */
console.log('loading data');
console.log(this);
this.setState({ chartOptions: chartOptions, data1: data1, data2: data2, data3: data3, data4: data4, data5: data5, data6: data6, loaded: true });
// this.forceUpdate();
}).then()
.catch(function (error) {
console.log(error);
})
}
componentWillUpdate(nextProps) {
this.initComp(nextProps.params.clientID);
}
shouldComponentUpdate(nextProps) {
return nextProps.params.clientID != this.props.params.clientID;
}
componentWillMount() {
this.initComp(this.props.params.clientID);
}
render() {
console.log('parent rendering')
// removed all unnecessary code below
return (
<div className="wrapper wrapper-content animated fadeIn">
<div className="row">
<div className="col-lg-4">
<div className="ibox">
<div className="ibox-content">
<MetricsColumnChart metricsData={this.state.data1} options={this.state.chartOptions} />
</div>
</div>
</div>
</div>
</div>
)
}
}
/**
* Map the state to props.
*/
const mapStateToProps = (state) => ({
...state
});
/**
* Map the actions to props.
*/
const mapDispatchToProps = (dispatch) => {
return bindActionCreators(Actions, dispatch)
};
/**
* Connect the component to
* the Redux store.
*/
export default connect(
mapStateToProps,
mapDispatchToProps
)(ClientDash)
兒童
import React, { Component } from 'react';
import {Bar} from 'react-chartjs-2';
var _ = require('lodash');
class MetricsColumnChart extends Component {
render() {
console.log('child rendering')
return(
<Bar data={this.props.metricsData} options={this.props.options} />
)
}
}
export default MetricsColumnChart
這裏的控制檯的樣子。正如你所看到的,沒有重新渲染和「this」是正確的「this」:
如果家長沒有更新,孩子也不會。你必須相應地更新你的'shouldComponentUpdate'(它接受第二個參數'nextState') –
@TylerSebastian是對的。如果您使用控制檯登錄'shouldComponentUpdate',它應該到達那裏。它在那裏停了下來。 –
感謝您的幫助,您是對的。我只是在'shouldComponentUpdate'方法的返回中添加了一個'!(_。isEqual(nextState,this.state))'' – Couch