我初学react写了一个小组件,在更新组件状态的时候发现计算数据有些不正确。请教一下。
▼如下图:
目的是每增加一个苹果,苹果数量增加一个,同时更新总重&总计金额。
目前问题是,从0增加到1个苹果时,合计金额没有变化。请帮看一下哪里的问题。谢谢老司机。
good man one life safe.
▼部分相关代码如下
<body>
<p id="p01">
插件未正确加载
</p>
<script type="text/babel">
var BuyApple = React.createClass({
render: function () {
return (
<p >
<p>
购买<span>{this.state.shuLiang}</span>个苹果,
每个<span>{this.state.danZhong}</span>斤,
每斤<span>{this.state.danJia}</span>元,
一共<span>{this.state.zongZhong}</span>斤,
合计<span>{this.state.zongJi}</span>元。
</p>
<input type="button" value="增加苹果" onClick={ this.addApple}/>
<input type="button" value="减少苹果" onClick={ this.reduceApple}/>
<input type="button" value="增加单价" onClick={ this.addMoney}/>
<input type="button" value="减少单价" onClick={ this.reduceMoney}/>
</p>
);
},
getInitialState:function () {
return{
shuLiang: 0, //数量
danZhong: 0.5, //单重
danJia:2, //单价
zongZhong: 0, //总重
zongJi: 0, //总计
}
},
addApple:function () {
this.setState({ //▼问题八成出在这里
shuLiang: ++this.state.shuLiang, //苹果数量加1
zongZhong: this.state.shuLiang * this.state.danZhong, //苹果总重=数量*单重
zongJi: this.state.zongZhong * this.state.danJia, //总计=总重*单价
});
},
});
ReactDOM.render(
<BuyApple/>,
document.querySelector('#p01'),
);
</script>
</body>
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
最主要的原因是
setState是个异步的操作两个方案
按照楼上说的,总重在render里去算
setState有第二个参数,是个callback,可以拿到新的state,你可以在这个callback里去设置总重,甩一个文档当然,我建议你用第一种方案
你在同一个setState里设置数量和总重,实际上总重调用的this.state.shuLiang还没改变,还是之前的值。压根就不用保存太多的state。
state里面要存最少的值,能通过计算出来的都不能存
这个
zongJi不要放在state里面,在展示的时候直接算出来就行了。1:state要使用最小状态集合
明显,zongZhong和zongJi是可以通过前面三个state计算出来的。
2:建议在render里计算,不要在setState里是算。
3:问题的根本原因是@zhangfe的解释,为了性能优化,React的setState(new State, callback)是异步的,他甩的文档里说得很清楚。
没用过react,但是我猜测问题大概是这样的。我认为setState方法大概是这样的
而你的代码运行过程实际上是
然后再
this.setState(obj);
这时候obj里面的值已经计算完了,所以导致的结果不正确。
所以你可以
....多看下文档,很多api后面都不止我们常用的一个参数,还有能不能用英文,拼音看着挺别扭的。养成个好习惯嘛,大家共勉。
其实吧,使用定时器是个很好的选择,在didMount的时候调用计时器,在willMount的时候清空计时器
按照官方文档,state应该保存尽量少的变量,其它可以算出来的再在render函数中更新