当前位置: 首页 > 知识库问答 >
问题:

React.js setState不工作[重复]

洪国兴
2023-03-14

我是React中的一个noob,正在尝试为水相制作一个简单的应用程序,用户输入一个数字,然后根据数值显示水的状态,例如,如果他输入212,它应该是气体,12应该是固体,但由于某些原因,它没有正确显示数值,非常感谢任何帮助!!!

class App extends React.Component {

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

    handlenum1Change(evt) {
        console.log(evt.target.value);
        this.setState({
            temp: Number(evt.target.value)
        });

        let temp = this.state.temp
        if (temp > 100) {
            this.setState({
                msg: "boiling"
            })
        } else if (temp < 32) {
            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")
);
html prettyprint-override"><div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

共有3个答案

苏承载
2023-03-14

setState不是立即更改状态的必要方法,而是您请求尽快对更改组件状态做出反应的请求(请参见此处)。

您应该考虑的另一个重要因素是,eventReact使用的不是标准HTML事件,而是由React自身创建的用于包装标准事件的SyntheticEvent,出于“性能原因”,此SyntheticEvent将尽快被丢弃。

现在,你的问题很容易通过改变

const temp = this.state.temp

const temp = Number(evt.target.value)

但是在使用React组件的状态时,您应该记住上面两个因素。

编辑:在使用setState的回调版本时,有关syntheticevents的考虑尤其重要,因为从该回调中访问值很可能不包含触发onChange事件的输入值,因此,您必须将其存储在回调范围外的变量中,例如:

handleInputChange = (event) => {
     const value = event.target.value

     this.setState(prevState => {
          return { myValue: prevState.value + value }
     })
}
陶英达
2023-03-14

setState是异步的。另外,如果根据当前状态(this.state.temp)设置state(setState({msg:...})),则必须使用setState的回调版本。

但是在这种情况下,您可以同时设置tempmsg,因为它们都是从状态之外的东西(来自输入的temp)工作的:

handlenum1Change(evt) {
    console.log(evt.target.value);
    const temp = Number(evt.target.value);
    let msg;

    if (temp > 100) {
        msg = "boiling";
    } else if (temp < 32) {
        msg = "frozen";
    } else {
        msg = "liquid";
    }
    this.setState({temp, msg});
}
class App extends React.Component {

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

    handlenum1Change(evt) {
        console.log(evt.target.value);
        const temp = Number(evt.target.value);
        let msg;

        if (temp > 100) {
            msg = "boiling";
        } else if (temp < 32) {
            msg = "frozen";
        } else {
            msg = "liquid";
        }
        this.setState({temp, msg});
    }

    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")
);
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
戎俊
2023-03-14

setState是异步的,不会立即更新状态。它在更新之前收集多个状态更改。这意味着,this.state不会立即保存您的新值。

或在此处引用React文档:

setState()并不总是立即更新组件。它可以批处理更新或将更新推迟到以后。这使得调用setState()后立即读取This.state成为一个潜在的陷阱。相反,使用componentdiddupdatesetState回调(setState(updater,callback)),这两种回调都保证在应用更新后触发。如果需要基于上一个状态设置状态,请阅读下面的updater参数。

相反,在设置新状态之前,反过来做,并使用用户输入。这样,您也可以同时集体设置温度和消息:

const temp = Number(evt.target.value);
let msg = '';
if (temp > 100) {
  msg = 'boiling';
} else if (temp < 32) {
  msg = 'frozen';
} else {
  msg = 'liquid';
}

this.setState({
  temp,
  msg,
});
 类似资料:
  • 我创建了这段代码,其中大部分代码都是使用toUpperCase,它应该使单词的每个首字母都大写。没有错误,因此我不确定该方法当前为何不起作用。为什么会这样呢。

  • 我正在使用泽西开发一个API,并希望将其准备好部署到Google App Engine。但是,当我在Postman上测试时,GET函数有效,但POST函数无效。我只收到一条简短的错误消息,即“错误415不支持的媒体类型”,我无法确定哪里出了问题。 请求资源类 请求服务等级 网状物XML 提前感谢所有帮助我指出并解决问题并回答我问题的人。

  • 我正试图在Android中做一个向后兼容的工具栏,我遵循了多种风格指南中给出的所有建议来尝试和完成这个。然而,它似乎仍然不起作用。风格是这样的: 这是工具栏: 这是onCreate方法的主要活动: 不太确定出了什么问题,因为我遵循了许多消息来源给出的所有说明。这是日志: 我花了几个小时研究这段代码,以及无数的教程和StackOverflow问题,但是毫无用处。如果有人能帮助我,我将不胜感激。提前感

  • 我有三个数组来制作一个tableView和第二个ViewController。一个显示tableView上每个节的标题,一个显示标题,还有一个显示每个单元格的链接。当我构建并点击其中一个单元格时,我会得到: 致命错误:在展开可选值时意外发现nil 在这条线上: 下面是第二个视图控制器代码:

  • 我正在调用一个API来获取一些数据。API响应以格式返回日期和时间,但当我使用将其解析为时,它显示而不是我从API获得的date.String格式是。 这是我的代码。