我正在更新map
内的状态元素的属性
computePiePercentages(){
var denominator = 1600
if (this.state.total < 1600){
denominator = this.state.total
}
return this.state.pieChartData.map((item, index) => {
return {
...item,
y: Number((item.y / denominator).toFixed(1)) * 100
}
})
}
但是,当我使用pieChartData
显示图表时-y
尚未更新。我检查了数学公式以确保在computePiePercentages
map
函数是否像setState
一样异步?在显示结果之前,如何确保等待更新发生?
以下是相关代码的其余部分:
class Budget extends React.Component {
computePiePercentages(){
var denominator = 1600
if (this.state.total < 1600){
denominator = this.state.total
}
return this.state.pieChartData.map((item, index) => {
return {
...item,
y: Number((item.y / denominator).toFixed(1)) * 100
}
})
}
computeTotals(){
var runningTotal = 0
var pieArray = []
var beyondBudget = {}
Object.entries(this.state.data.selectedQuestions).map((element, j) => {
console.log("hi here")
console.log(element)
//return selectedQuestions.map((val, j) => {
const value = Object.values(element[1])[0]
const name = element[0]
runningTotal += value
if(runningTotal <= 1600){
let pieSlice =
{
x: name,
y: value
};
pieArray = pieArray.concat(pieSlice)
}
else {
if (Object.keys(beyondBudget).length == 0) {
beyondBudget[name] = {};
beyondBudget[name] = runningTotal - 1600;
let pieSlice =
{
x: name,
y: value - (beyondBudget[name])
};
pieArray = pieArray.concat(pieSlice)
}
if (!beyondBudget[name]) {
beyondBudget[name] = {};
}
if (Object.keys(beyondBudget).length > 1) {
beyondBudget[name] = value;
}
}
});
this.setState({
pieChartData: pieArray,
total: runningTotal,
beyondBudget: beyondBudget,
}, () => {
this.computePiePercentages();
});
}
render() {
const {
data,
pieChartData,
beyondBudget,
showResults,
total
} = this.state;
const questions = data.questions;
return (
<div>
{questions.map((q, i) => (
<UL key={i}>
<li>
<h4>{q.text}</h4>
</li>
<li>
<Options
state={this.state}
q={q}
i={i}
handler={this.handleInputChange}
/>
</li>
</UL>
))}
<button onClick={(event) => {
this.computeTotals();
this._showResults(true);
}}>Click</button>
{console.log(this.state.showResults)}
{this.state.showResults &&
(<div>
<VictoryPie
colorScale="blue"
data={pieChartData}
labels={d => `${d.x}: ${d.y}%`}
style={{ parent: { maxWidth: '50%' } }}
/>
{Object.keys(beyondBudget).length > 0 && (
<div>
<Table>
<tbody>
<tr>
<th>Out of Budget</th>
</tr>
<BrokeBudget
beyondBudget={beyondBudget}
/>
</tbody>
</Table>
</div>
)}
</div>
)
}
</div>
);
}
}
答案 0 :(得分:1)
正如其他人所提到的,数组的.map()
函数返回一个新数组,而不更改旧数组。因此,目前的this.computePiePercentages()
会基于this.state.pieChartData
创建一个新数组并返回该新数组。此操作不会更改this.state.pieChartData
。
您正在从this.computePiePercentages()
的回调函数中调用this.setState()
。这只是一个函数,除了setState()
完成更改状态时会调用之外,没有其他特殊属性。因此,要在computePiePercentages()
内进一步更新状态,您需要再次调用setState()
。
有两种选择:
this.computePiePercentages
更新回调函数中的状态:this.setState({
pieChartData: pieArray,
total: runningTotal,
beyondBudget: beyondBudget,
}, () => {
this.setState({
pieChartData: this.computePiePercentages()
});
});
this.computePiePercentages
中的状态:this.setState({
pieChartData: this.state.pieChartData.map((item, index) => {
return {
...item,
y: Number((item.y / denominator).toFixed(1)) * 100
}
})
});