我正在研究React文档的这一部分:https://reactjs.org/docs/lifting-state-up.html。
在我的一个项目中,我遇到了类似的问题,但有细微的差别。我们可以使用与文档相同的示例,并进行一些改动以适合我的问题:让我们假设我拥有<TemperatureInput />
组件而不是<Sensor />
。该传感器以两种不同的形式捕获温度和压力。我的第一个想法是捕获这些压力和温度输入,然后进入State(状态),然后将其传递给Sensor的props changeHandler函数,该函数实际上是一个定义并在父组件上工作的函数。这最后一部分是React文档的建议,尽管它们没有将State传递给函数,但只是一个变量(event.target.value)。因此,作为示例,我们将遇到类似这样的情况:
class Sensor extends React.Component {
constructor(props) {
super(props);
this.state = {temperature:'',
pressure: ''}
this.handleTemperatureChange = this.handleTemperatureChange.bind(this);
this.handlePressureChange = this.handlePressureChange.bind(this);
}
handleTemperatureChange(e) {
this.setState(temperature:e.target.value);
this.props.onChange(this.state);
}
handlePressureChange(e) {
this.setState(pressure:e.target.value);
this.props.onChange(this.state);
}
render() {
const temperature = this.props.temperature;
return (
<fieldset>
<legend>Enter temperature and pressure:</legend>
<input value={this.state.temperature}
onChange={this.handleTemperatureChange} />
<input value={this.state.pressure}
onChange={this.handlePressureChange} />
</fieldset>
);
}
}
我修改后的方法唯一的问题是State是异步更新的,所以当我将State传递给onChange props函数时,实际上可能是在传递先前的状态。
我不确定该如何处理。
答案 0 :(得分:2)
正确。 React状态更新是异步的,因此如果尝试在使更新入队后立即访问状态,它仍将是 current 渲染周期中的状态,而不是您期望在 next <下看到的状态/ em>渲染周期。
使用组件生命周期方法(例如componentDidUpdate
来处理“反应”以状态更新,并正确发出副作用,例如调用传递的回调。
class Sensor extends React.Component {
...
handleTemperatureChange(e) {
this.setState(temperature:e.target.value);
}
handlePressureChange(e) {
this.setState(pressure:e.target.value);
}
componentDidUpdate(prevProps, prevState) {
const { pressure, temperature } = this.state;
if (prevState.pressure !=== pressure ||
prevState.temperature !== temperature
) {
this.props.onChange(state);
}
}
render() {
...
}
}
的替代方法是在状态更新后使用this.setState
回调函数(第二个参数)运行函数 ,尽管我认为这种模式应该避免。 (如果误用,IMO可能会引起更多的问题,而只能解决生命周期功能)
class Sensor extends React.Component {
...
handleTemperatureChange(e) {
this.setState(
temperature:e.target.value,
() => this.props.onChange(this.state),
);
}
handlePressureChange(e) {
this.setState(
pressure:e.target.value,
() => this.props.onChange(this.state),
);
}
render() {
...
}
似乎您的树中有较高的 压力和温度状态,因此我很好奇这种情况是否发生,并且如果只是将它们作为道具代理到输入中,将使更有意义,例如:
const Sensor = ({ pressure, onChange, temperature }) => {
const handleTemperatureChange = (e) => {
onChange({ temperature: e.target.value });
}
const handlePressureChange = (e) => {
onChange({ pressure: e.target.value });
}
return (
<fieldset>
<legend>Enter temperature and pressure:</legend>
<input value={temperature} onChange={handleTemperatureChange} />
<input value={pressure} onChange={handlePressureChange} />
</fieldset>
);
}
答案 1 :(得分:1)
setState
收到一个回调,该回调将在应用状态更改后触发。您可以在文档here中看到它。
this.setState({ ... }, () => this.props.onChange(this.state));