React.js setState无效

时间:2018-05-23 15:47:23

标签: javascript reactjs

我是React中的菜鸟并试图为用户输入数字的水相制作一个简单的应用程序,然后根据它应该显示水的状态的值,例如,如果他进入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")
);
<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>

4 个答案:

答案 0 :(得分:6)

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

或者引用React文档:

  

setState()并不总是立即更新组件。有可能   批量或推迟更新,直到稍后。这使得阅读this.state   在致电setState()潜在的陷阱之后。相反,使用   componentDidUpdatesetState回调(setState(updater, callback)),其中任何一个都保证在更新后触发   已经应用。如果需要根据以前的状态设置状态   state,请阅读下面的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,
});

答案 1 :(得分:1)

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

但是在这种情况下,您可以同时设置tempmsg,因为他们都是在州外的某些工作(来自input的临时工作):

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});
}

&#13;
&#13;
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")
);
&#13;
<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>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

setState不是立即更改状态的命令式方法,而是您对React做出的请求,以便立即更改组件的状态可以(见here)。

您应该考虑的另一个重要事项是event React使用的不是标准的HTML事件,而是由React自己创建的SyntheticEvent来包装标准事件,而{{1}由于“表现原因”,将尽快丢弃。

现在,通过更改

可以轻松解决您的问题
SyntheticEvent

const temp = this.state.temp

但是在使用React Component的状态时应该记住以上两个因素。

修改:在使用const temp = Number(evt.target.value) 的回调版本时,对SyntethicEvent s的考虑尤为重要,因为从该回调中访问该值很可能包含触发setState事件的输入值,因此您必须将其存储在回调范围之外的变量中,例如:

onChange

答案 3 :(得分:-1)

enter image description here enter image description here
enter image description here由于除了比较之外的其他任何地方都没有使用this.state.temp,因此可以在变量中指定值并进行比较。仅供参考,setState不会立即反映这些变化。

handlenum1Change(evt) {
        let temp = evt.target.value;
        if (temp > 100) {
            this.setState({
                msg: "boiling"
            })
        } else if (temp < 32) {
            this.setState({
                msg: "frozen"
            })
        } else {
            this.setState({
                msg: "liquid"
            })
        }
    }