>我有一个带有构造函数的组件:
<code lang="javascript">
class Day extends Component {
constructor(props) {
super(props);
this.state = {
calories: 0,
fat: 0,
protein: 0,
carbs: 0,
};
this.caloriesCalculate();
}
</code>
我有一个方法卡路里计算((。它有以下代码:
<code lang="javascript">
caloriesCalculate() {
var fat = 0;
var protein = 0;
var carbs = 0;
var calories = 0;
const { dataArray, mealPlan, date } = this.props;
const { products } = dataArray;
var timestamp = date._i/1000;
Object.keys(mealPlan[timestamp]).map(function(type) {
var product = products[mealPlan[timestamp][type]];
fat += product.fat/1000;
protein += product.protein/1000;
carbs += product.carb/1000;
calories += product.calories/1000;
});
var nutritions = {
calories: calories,
fat: fat,
protein: protein,
carbs: carbs,
}
this.setState(nutritions);
}
</code>
当我将其分配给按钮单击时,该方法效果很好:
<code lang="javascript">
onClick={() => this.caloriesCalculate()}
</code>
但是,如果该方法是从构造函数执行的,则状态的值为零。同时,如果我做console.log(nutritions);
,它在控制台中显示有效值,但在 render(( 中 - 零值。
在渲染((中,我有这个:
<code lang="javascript">
<li className='day-calories'><b>Calories:</b> {calories}, <b>Fat:</b> {fat}g, <b>Protein:</b> {protein}g, <b>Carbs:</b> {carbs}g</li>
</code>
如果我将在构造函数中具有来自父组件属性的值- 它即将具有相同的计算,但在父组件内。
我可以在构造函数中进行计算 - 但它也是关于双重计算的(onClick={() => this.caloriesCalculate()}
- 它不是用于测试或调试,我在此方法中使用此按钮(。
我做错了什么?为什么this.calculateCalories()
不从构造函数获取状态有效数据?
setState
- 这是构造函数中的异步,尝试将函数调用移动到另一个生命周期,如componendDidMount
class Day extends Component {
state = {
calories: 0
...
};
componendDidMount = () => {
this.caloriesCalculate();
};
caloriesCalculate = () => {
// ... set nutritions
this.setState(nutritions);
};
}
旁注:避免使用
var
编写更简洁的代码。
反应组件的构造函数只在挂载 DOM 之前调用一次。 此外,不应在构造函数中调用 setState。因此,首先调用构造函数,然后调用 render 方法。换句话说,在列表显示在屏幕上之前,您在构造函数中调用this.caloriesCalculate();
。要解决您的问题,您需要使用 React 生命周期钩子。你需要的那个是componentDidMount()
constructor(props) {
super(props);
this.state = {
calories: 0,
fat: 0,
protein: 0,
carbs: 0,
};
}
componentDidMount() {
this.caloriesCalculate();
}
caloriesCalculate() {
// your code.
}
您可以在此处阅读有关生命周期钩子的更多信息。