React.js setState 不起作用[重复]

Posted

技术标签:

【中文标题】React.js setState 不起作用[重复]【英文标题】:React.js setState not working [duplicate] 【发布时间】:2018-11-02 16:37:38 【问题描述】:

我是 React 的菜鸟,正在尝试为水相制作一个简单的应用程序,用户输入一个数字,然后根据该值显示水的状态,例如,如果他输入 212,它应该说 gas 和 for 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>

【问题讨论】:

欢迎来到 Stack Overflow!在寻求帮助时,请花时间以合理、一致的缩进来格式化您的代码,并且不要使用大量不必要的空格。 (当寻求帮助时也是个好主意。) 感谢您在问题中包含所有必要的代码。如您所见,我更新了问题以使用 Stack Snippets(页面中类似于 &lt;&gt; 的工具栏按钮)制作一个 可运行版本。 Stack Snippets 支持 React,包括 JSX; here's how to do one. 【参考方案1】:

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

或者在这里引用 React 文档:

setState() 并不总是立即更新组件。有可能 批处理或推迟更新。这使得阅读this.state 在致电setState() 之后,这是一个潜在的陷阱。相反,使用 componentDidUpdatesetState 回调 (setState(updater, callback)),其中任何一个都保证在更新后触发 已应用。如果需要根据前面的设置状态 状态,请阅读下面的更新程序参数。


相反,在设置新状态之前使用用户输入进行操作。这样你也可以同时设置温度和信息:

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

【讨论】:

【参考方案2】:

除了比较之外,您没有在其他任何地方使用 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"
            )
        
    

【讨论】:

【参考方案3】:

setState is asynchronous。另外,如果您根据当前状态 (this.state.temp) 设置状态 (setState(msg: ...)),您必须使用 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);

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>

【讨论】:

【参考方案4】:

setState 不是立即更改状态的必要方法,而是您向 React 发出的请求,以尽快更改组件的状态(见here)。

你应该考虑的另一件重要的事情是,event React 使用的不是标准的 html 事件,而是由 React 自己创建的用于包装标准事件的SyntheticEvent,并且这个SyntheticEvent 将尽快被丢弃尽可能出于“性能原因”。

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

const temp = this.state.temp

const temp = Number(evt.target.value)

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

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

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

     this.setState(prevState => 
          return  myValue: prevState.value + value 
     )

【讨论】:

以上是关于React.js setState 不起作用[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Maxlength 不起作用 React Js

将元素推送到数组时反应setstate不起作用

setState 在 setInterval 中不起作用 [重复]

React JS路由路径不起作用[重复]

componentDidMount 内的 setState [重复]

TypeError:未定义不是对象(评估'this.setState')[重复]