[英]What is the correct way to set state in React
Honestly, this is my day 1 in ReactJS.老实说,这是我在 ReactJS 中的第一天。 I'm learning some small-small things like
state
.我正在学习一些小的东西,比如
state
。 I've created a small program for the toggle button.我为切换按钮创建了一个小程序。 It will simply display "Hello world!"
它只会显示“Hello world!” or display nothing when the button is toggled.
或在按钮切换时不显示任何内容。 There's one thing that I didn't understand.
有一件事我不明白。 My code gives me an error when I use this syntax:
当我使用此语法时,我的代码给了我一个错误:
toggleHandler() {
const currentStatus=this.state.display;
this.setState({
display: !currentStatus
})
}
this.state is undefined
this.state 未定义
But the same code works perfectly If I change the syntax to a fat arrow function:但是如果我将语法更改为粗箭头函数,则相同的代码可以完美运行:
toggleHandler=()=> {
const currentStatus=this.state.display;
this.setState({
display: !currentStatus
})
}
I'll not waste your time.我不会浪费你的时间。 I've created an stackblitz .
我创建了一个stackblitz 。 Experts on the internet say that any call to
this.setState()
is asynchronous.互联网上的专家说,对
this.setState()
任何调用都是异步的。 So I tried using call back function
and IIFE
but got myself more confused and over-complicated.所以我尝试使用
call back function
和IIFE
但让自己更加困惑和过于复杂。 Please correct me.请纠正我。 I'm sorry this is a very childish question.
对不起,这是一个非常幼稚的问题。
There are a couple of ways.有几种方法。
One is to add in the constructor.一种是在构造函数中添加。 ES6 React.Component doesn't auto bind methods to itself .
ES6 React.Component 不会自动绑定方法到它自己。 You need to bind them yourself in constructor.
您需要自己在构造函数中绑定它们。 Like this
像这样
this.toggleHandler = this.toggleHandler.bind(this);
Another is arrow functions toggleHandler = (event) => {...}.
另一个是箭头函数
toggleHandler = (event) => {...}.
And then there is onClick={this.toggleHandler.bind(this)}
然后是
onClick={this.toggleHandler.bind(this)}
Yes, any setState call is asynchronous.是的,任何 setState 调用都是异步的。 You can check your log that it changes his status but not manipulate the dom.
你可以检查你的日志,它改变了他的状态,但不操纵 dom。 For manipulating the dom Any asynchronous call should be via a callback function.
对于操作 dom 任何异步调用都应该通过回调函数。
you can bind any state with this arrow function or this.state.bind(this).您可以使用此箭头函数或 this.state.bind(this) 绑定任何状态。
What the error message is telling you is that the this
object doesn't contain a property called state
.错误消息告诉您的是
this
对象不包含名为state
的属性。 What exactly this
refers to is a constant source of confusion in JS, except when inside an arrow function.究竟
this
是指是混乱的在JS的恒定源,除了当一个箭头函数内部。 Inside an arrow function, this
always refers to the context the arrow function appears in.在箭头函数内部,
this
总是指箭头函数出现的上下文。
The issue here is in the first example, this
refers to the context sent to the handler by the onClick event.这里的问题是在第一个示例中,
this
是指由 onClick 事件发送到处理程序的上下文。 This context does not contain a state
property.此上下文不包含
state
属性。 However, inside the arrow function, the this
keyword will refer to the JavaScript class that your arrow function exists in. This class does have the state
property.但是,在箭头函数内部,
this
关键字将引用您的箭头函数所在的 JavaScript 类。该类确实具有state
属性。
To get around this, you can use bind
(which outputs a copy of your function with the context set to whatever you supply it with. Or just use arrow functions. If it were me I would take the latter approach since this
has better defined and more consistent behaviour inside an arrow function. If you do want to use bind
, you would do this in your event handler declaration like so:为了解决这个问题,你可以使用
bind
(它输出你的函数的副本,上下文设置为你提供的任何内容。或者只是使用箭头函数。如果是我,我会采用后一种方法,因为this
有更好的定义和箭头函数内更一致的行为。如果你想使用bind
,你可以在你的事件处理程序声明中这样做:
onClick={this.toggleHandler.bind(this)}
The way you can use functions and previous state.您可以使用函数的方式和以前的状态。
1- Binding in constructor 1- 在构造函数中绑定
constructor() {
this.toggleHandler=this.toggleHandler.bind(this);
}
can define like this可以这样定义
toggleHandler=()=>{
this.setState(prev=>({
display: !prev.display
}))
}
2- arrow function (don't need to bind in constructor) 2-箭头函数(不需要在构造函数中绑定)
toggleHandler=()=>{
this.setState(prev=>({
display: !prev.display
}))
}
3- Inline binding 3- 内联绑定
<Button onClick={this.toggleHandler.bind(this)}>Toggle</Button>
function code功能码
toggleHandler=()=>{
this.setState(prev=>({
display: !prev.display
}))
}
4- Inline arrow function 4- 内联箭头函数
<Button onClick={()=>this.toggleHandler()}>Toggle</Button>
function code功能码
toggleHandler=()=>{
this.setState(prev=>({
display: !prev.display
}))
}
Note - Recommended to avoid inline functions for better performance
注意 - 建议避免使用内联函数以获得更好的性能
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.