setState 导致意外触发事件处理程序方法
setState causes unexpected trigger of event handler method
我正在使用调用 setState 的点击事件处理程序。但似乎 setState 会导致连续意外触发点击事件处理程序。
状态由对象(包含分钟和秒)组成,当我单击 html 元素时应该减少。
const sessionLength = {min: 25,
sec: 0}
this.state = {
breakLength: 5,
sessionLength: sessionLength,
sessionProcessed: sessionLength
}
这是点击事件处理程序:
startPomodoro(){
this.setState(prevState=>({sessionProcessed: {...prevState.sessionProcessed, sec: prevState.sessionProcessed.sec - 1}}));
};
和 JSX :
render(){
return(
<div class="ml-5">
<h1>Test</h1>
<div>Session</div>
<div><strong id="session">{this.state.sessionLength.min}:{this.state.sessionLength.sec}</strong></div>
<div><i id="play" class="fa fa-play" onClick={this.startPomodoro()}></i> <i id="pause" class="fa fa-pause" onClick={this.pausePomodoro()}></i></div>
</div>
)
}
因为它什么都不显示,所以我在点击事件处理程序 (startPomodoro) 中添加了一个警告语句,它在我没有点击的情况下执行了 startPomodoro 事件处理程序。
您正在调用处理程序 (startPomodoro()
) 而不是仅仅传递它 (startPomodoro
)。将您的代码更改为:
<i id="play" class="fa fa-play" onClick={this.startPomodoro}></i> <i id="pause" class="fa fa-pause" onClick={this.pausePomodoro}></i>
调用处理程序时,您有两种选择:
- 传递回调(最佳选择)
- 在渲染上声明一个匿名函数
传递回调
onClick={this.startPomodoro}
声明匿名函数
onClick={() => this.startPomodoro()}
请注意,如果您声明匿名函数,它可能会导致一些性能问题,如文档中所述:https://reactjs.org/docs/handling-events.html
The problem with this syntax is that a different callback is created each time the component renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering. We generally recommend binding in the constructor or using the class fields syntax, to avoid this sort of performance problem.
关于上述答案,传递箭头函数(onClick={ () => this.startPomodoro() }
)将完美工作。
如果要传递回调,则应将回调函数绑定到 this
引用。
像这样:
onClick={ this.startPomodoro.bind(this) }
我正在使用调用 setState 的点击事件处理程序。但似乎 setState 会导致连续意外触发点击事件处理程序。
状态由对象(包含分钟和秒)组成,当我单击 html 元素时应该减少。
const sessionLength = {min: 25,
sec: 0}
this.state = {
breakLength: 5,
sessionLength: sessionLength,
sessionProcessed: sessionLength
}
这是点击事件处理程序:
startPomodoro(){
this.setState(prevState=>({sessionProcessed: {...prevState.sessionProcessed, sec: prevState.sessionProcessed.sec - 1}}));
};
和 JSX :
render(){
return(
<div class="ml-5">
<h1>Test</h1>
<div>Session</div>
<div><strong id="session">{this.state.sessionLength.min}:{this.state.sessionLength.sec}</strong></div>
<div><i id="play" class="fa fa-play" onClick={this.startPomodoro()}></i> <i id="pause" class="fa fa-pause" onClick={this.pausePomodoro()}></i></div>
</div>
)
}
因为它什么都不显示,所以我在点击事件处理程序 (startPomodoro) 中添加了一个警告语句,它在我没有点击的情况下执行了 startPomodoro 事件处理程序。
您正在调用处理程序 (startPomodoro()
) 而不是仅仅传递它 (startPomodoro
)。将您的代码更改为:
<i id="play" class="fa fa-play" onClick={this.startPomodoro}></i> <i id="pause" class="fa fa-pause" onClick={this.pausePomodoro}></i>
调用处理程序时,您有两种选择:
- 传递回调(最佳选择)
- 在渲染上声明一个匿名函数
传递回调
onClick={this.startPomodoro}
声明匿名函数
onClick={() => this.startPomodoro()}
请注意,如果您声明匿名函数,它可能会导致一些性能问题,如文档中所述:https://reactjs.org/docs/handling-events.html
The problem with this syntax is that a different callback is created each time the component renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering. We generally recommend binding in the constructor or using the class fields syntax, to avoid this sort of performance problem.
关于上述答案,传递箭头函数(onClick={ () => this.startPomodoro() }
)将完美工作。
如果要传递回调,则应将回调函数绑定到 this
引用。
像这样:
onClick={ this.startPomodoro.bind(this) }