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(页面中类似于<>
的工具栏按钮)制作一个 可运行版本。 Stack Snippets 支持 React,包括 JSX; here's how to do one.
【参考方案1】:
setState
是异步的,不会立即更新状态。它在更新之前收集多个状态更改。
这意味着,this.state
不会立即保留您的新值。
或者在这里引用 React 文档:
setState()
并不总是立即更新组件。有可能 批处理或推迟更新。这使得阅读this.state
在致电setState()
之后,这是一个潜在的陷阱。相反,使用componentDidUpdate
或setState
回调 (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
的回调版本。
但在这种情况下,您可以同时设置 temp
和 msg
,因为它们都在状态之外的东西(来自 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
的回调版本时,关于SyntethicEvent
s 的考虑尤其重要,因为从该回调中访问值很可能不包含输入的值触发了onChange
事件,因此您必须将其存储在回调范围之外的变量中,例如:
handleInputChange = (event) =>
const value = event.target.value
this.setState(prevState =>
return myValue: prevState.value + value
)
【讨论】:
以上是关于React.js setState 不起作用[重复]的主要内容,如果未能解决你的问题,请参考以下文章
setState 在 setInterval 中不起作用 [重复]