Cou*_*uch 2 setstate reactjs axios
tldr; version:父类在setState调用后没有重新渲染...
我有一个仪表板视图,呈现多个组件.加载数据的子组件工作得很好.但我有仪表板的另一部分,我计划使用相同的数据集加载同一组件的多个版本.因此,我不是对同一个数据集进行6次api调用,而是通过父级将数据拉入并将其发送给子级.此外,我正在使用路由参数来指示要查找的公司.
包含自己的api调用的组件工作得很好,与路径参数一起正常运行.这是我在父母那里进行api调用的组件,我遇到了问题.父级正在渲染,然后是子级,然后api调用完成并设置状态,但不重新加载.因此,当路径参数发生变化时,组件会显示前一次点击的数据(基本上总是落后一个).
我已经尝试更改哪些反应事件将它绑定到,我使用映射函数,确保"this"是我想要的"this"(它是)...没有骰子.我知道它正在正确地更新状态,如果我在forceUpdate()中显示正确的数据(但我不能这样做,它会强制我将forceUpdate()添加到react更新方法中,这将导致它不断重新加载).
有任何想法吗??这是一些精简/混淆的代码:
亲
...
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)
Run Code Online (Sandbox Code Playgroud)
儿童
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
Run Code Online (Sandbox Code Playgroud)
问题出在你的身上shouldComponentUpdate.现在,只有当new的道具clientID与当前道具不同时,它才会返回true clientID.因此,当您this.setState()在API调用结束时运行时,组件不会更新,因为您没有收到新的道具.
基本上,
有两种方法可以解决这个问题:
shouldComponentUpdate以便React决定组件何时更新(当您运行this.setState或接收新更新时)shouldComponentUpdate是nextState,和比较新旧状态,以确定何时该组件将更新.顺便说一句,我看到你有API调用componentWillMount.你应该使用componentDidMountisntead 有一些很好的理由.
| 归档时间: |
|
| 查看次数: |
3326 次 |
| 最近记录: |