You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React.js setState不生效求助:水相态判断应用状态显示异常

Fixing Your Water State Detection App

Hey there! I see you're getting started with React and ran into a common pitfall with state updates—let's get your app working correctly.

The Root Problem

Your code has an issue with React's setState being asynchronous. When you call this.setState({ temp: Number(evt.target.value) }), React doesn't update the state immediately. So when you try to read this.state.temp right after that line, you're still getting the old value from before the update. That's why your state messages (boiling/frozen/liquid) aren't matching the temperature you just entered.

Two Simple Fixes

Fix 1: Use setState's Callback Function

React lets you pass a callback to setState that runs after the state has been fully updated. We can move our temperature check into this callback to ensure we're using the latest temp value:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { 
      msg: "liquid", 
      temp: 0 
    };
    this.handlenum1Change = this.handlenum1Change.bind(this);
  }

  handlenum1Change(evt) {
    const newTemp = Number(evt.target.value);
    // Update temp first, then run the state check in the callback
    this.setState({ temp: newTemp }, () => {
      const { temp } = this.state;
      if (temp > 100) {
        this.setState({ msg: "boiling" });
      } else if (temp < 32) { // Note: 32°F is freezing, 0°C—adjust if you meant Celsius!
        this.setState({ msg: "frozen" });
      } else {
        this.setState({ msg: "liquid" });
      }
    });
  }

  render() {
    return (
      <div>
        <h1>{this.state.msg}</h1>
        <form className="form-inline">
          <div className="form-group">
            <label> Temp: </label>
            <input 
              type="number" 
              onChange={this.handlenum1Change} 
              className="form-control" 
            />
          </div>
        </form>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));

Fix 2: Use the Input Value Directly (Even Simpler!)

Since we already have the new temperature value from evt.target.value, we don't even need to wait for state to update to run our check. We can use that value directly:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { 
      msg: "liquid", 
      temp: 0 
    };
    this.handlenum1Change = this.handlenum1Change.bind(this);
  }

  handlenum1Change(evt) {
    const newTemp = Number(evt.target.value);
    let newMsg = "liquid";
    
    if (newTemp > 100) {
      newMsg = "boiling";
    } else if (newTemp < 32) {
      newMsg = "frozen";
    }

    // Update both state properties in one go
    this.setState({ 
      temp: newTemp,
      msg: newMsg 
    });
  }

  render() {
    return (
      <div>
        <h1>{this.state.msg}</h1>
        <form className="form-inline">
          <div className="form-group">
            <label> Temp: </label>
            <input 
              type="number" 
              onChange={this.handlenum1Change} 
              className="form-control" 
            />
          </div>
        </form>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));

Quick Note About Temperature Scales

I noticed you're using 32 as the freezing point and 100 as boiling—just a heads up that's Fahrenheit! If you intended to use Celsius, swap those values to 0 (freezing) and 100 (boiling) instead. Easy tweak if needed.

Your HTML Dependencies Are Solid

Your existing HTML setup with the React scripts and root div is totally fine for this app—no changes needed there.

Give either of these fixes a try, and your water state should update correctly with every temperature input!

内容的提问来源于stack exchange,提问作者Leon Bogod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:50:41