我有一个存储状态的主要组件,并有一个名为handleBtnClick的函数来操作状态值。
我有另一个组件在按下按钮时调用函数handleBtnClick。我有一个displayComponent,我传递状态值以显示在窗体中。
我知道setState是异步的,所以displayComponent值总是落后一步。如何使用setState中的回调来解决这个问题,还是有另一种方法?
MainComponent
class SomeComponent extends React.Component {
constructor (props) {
super (props)
this.state = {value: 1}
}
handleBtnClick = (values) => {
const newValue = this.state.value * values;
this.setState({value: newValue});
}
render() {
return (
<div>
<ButtonComponent onClick={this.handleBtnClick} />
<DisplayComponent displayValue={this.state.value}/>
</div>
);
}
}
ButtonComponent
class ButtonComponent extends React.Component {
render() {
return (
<div>
<button onClick={() => this.props.onClick(123)}> // pretent this value always changes
Button
</button>
</div>
);
}
}
DisplayComponent
class DisplayComponent extends React.Component {
render() {
return (
<div>
{this.probs.displayValue}
</div>
);
}
}
修改
沙盒示例(感谢Shubham):https://codesandbox.io/s/5kx9yk7934
在第一个按钮上单击标签中显示的值为0,即使它应该是4.在第二次单击时它会更新为4.
如何在第一次点击时确保该值始终正确(即4)仅使用状态值进行计算。
答案 0 :(得分:0)
setState将更新您的状态,并且在状态更改时,您的主要组件将以新状态重新渲染,因此您的isDisplayComponent将重新渲染。
你的DislayComponent有一个拼写错误:this.probs
您的按钮和显示都可以是无状态组件:
const DisplayComponent = ({displayValue}) => <div>{displayValue}</div>
由于onClick被反应用作点击监听器,因此更喜欢传递handleClick道具而不是onClick。
const ButtonComponent = ({handleClick}) => <div><button onClick={() => handleClick(123)}> </button></div>
答案 1 :(得分:0)
在您的沙箱中,SomeComponent
组件未正确处理状态:有多个setState
调用,这是异步的,并且还存储了三个值(value1,value2,total),当它只需要一个(要添加一堆操作数)时,你可以从每个渲染中派生总计:
import React from "react";
import { render } from "react-dom";
class ButtonComponent extends React.Component {
render() {
return (
<div>
<button onClick={() => this.props.onClick(2)}>
{" "}
// pretent this value always changes Button
</button>
</div>
);
}
}
class DisplayComponent extends React.Component {
render() {
return <div>{this.props.displayValue}</div>;
}
}
class SomeComponent extends React.Component {
constructor(props) {
super(props);
this.state = { stack: [] };
this.get_total = this.get_total.bind(this);
}
handleBtnClick = value => {
this.setState({ stack: this.state.stack.concat(value) });
};
get_total() {
return this.state.stack.reduce((result, value) => {
return result + value;
}, 0);
}
render() {
return (
<div>
<ButtonComponent onClick={this.handleBtnClick} />
<DisplayComponent displayValue={this.get_total()} />
</div>
);
}
}
render(<SomeComponent />, document.getElementById("root"));