[英]Why does ReactJS sets state when calling setState inside setTimeout?
In a simple reactJS class, this.setState() didn't actually set the state. 在一个简单的reactJS类中,this.setState()实际上并未设置状态。 I know it is called asynchronously but even when the component renders again, the state wasn't mutated. 我知道它被异步调用,但是即使组件再次呈现,状态也不会发生变化。 So this.state.showModal
is false
when component is mounted (as expected) then it is true
"forever". 因此,在安装组件时(如预期的那样), this.state.showModal
为false
,然后“永远”为true
。
here's a simple example : 这是一个简单的例子:
class MyComponent extends Component {
constructor (props) {
super(props)
this.state = {
showModal: false
}
this.showModal = this.showModal.bind(this)
this.hideModal = this.hideModal.bind(this)
}
showModal () {
this.setState({ showModal: true })
}
hideModal () {
this.setState({ showModal: false })
}
render () {
console.log(this.state.showModal) // Outputs true even after the hideModal() call
return (
<Components>
<div onClick={this.showModal}>
{
this.state.showModal === true
? <Modal
handles={handles}
close={this.hideModal}
/>
: '+'
}
</div>
</Components>
)
}
}
Here's the Modal Component : 这是模态组件:
class Modal extends Component {
render () {
return (
<div className='configurator-modal'>
<button className='close' onClick={this.props.close}> x </button>
Modal
</div>
)
}
}
But, when I replace the hideModal
function with a timeout like this : 但是,当我用这样的超时替换hideModal
函数时:
setTimeout(() => this.setState({ showModal: false }), 0)
The state is mutated and rendered as intended. 状态被突变并按预期方式呈现。
I'm just wondering why ReactJS could possibly reset state internally or prevent a state from mutating ? 我只是想知道为什么ReactJS可能在内部重置状态或阻止状态发生变化?
Edit : Calls to hideModal and showModal added 编辑:添加了对hideModal和showModal的调用
You have a click
handler on the parent element too which call the showModal
and change the state to true. 在父元素上也有一个click
处理程序,它会调用showModal
并将状态更改为true。
When you click close
button, that will call hideModal
function, which will change the state to false
but that click will propagate to parent element as well, which will call showModal
which make it true
again. 当您单击close
按钮时,这将调用hideModal
函数,该函数会将状态更改为false
但是该单击也将传播到父元素,这将调用showModal
使其再次变为true
。 Therefore it always remains true
. 因此,它始终是true
。
Solution: Remove showModal
click handler from the parent element and put it where exactly you want it to be (i guess you want it on +
). 解决方案:从父元素中删除showModal
单击处理程序,并将其放置在您想要的位置(我想在+
上放置它)。
Since there is no plunker to play around, I am going to take a guess. 由于没有小玩意儿在玩,所以我要猜测一下。
div
being the parent of <Modal>
, when click event is triggered on the Modal
, it is also being propagated to div
. div
是<Modal>
的父级,当在Modal
上触发click事件时,它也将传播到div
。 So showModal
state is set to false
by hideModal()
function and set back to true
by showModal()
function. 因此,由hideModal()
函数将showModal
状态设置为false
,并通过showModal()
函数将其设置为true
。
When hideModal()
uses setTimeout()
, it is getting called after showModal()
is called. 当hideModal()
使用setTimeout()
,将在调用showModal()
之后调用它。
Try adding event.stopPropagation
in hideModal()
function, it might work. 尝试在hideModal()
函数中添加event.stopPropagation
,它可能会起作用。
Alternatively, you should add showModal()
as onClick handler for the +
sign instead of whole parent div. 另外,您应该将showModal()
作为+
符号(而不是整个父div showModal()
添加为onClick处理程序。 Please find the code below: 请在下面找到代码:
<Components>
<div>
{
this.state.showModal === true
? <Modal
handles={handles}
close={this.hideModal}
/>
: <div onClick={this.showModal}>'+'</div>
}
</div>
</Components>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.