Reputation: 961
I am trying to show/hide a modal when a user clicks on a item inside a list. The modal shows up as planned but cannot be hidden. When _dismiss()
is called, setState
executes but when I console.log
the state
inside the callback, the parameter show
is still true.
Why is this happening?
Message.jsx
export default class Message extends React.Component {
constructor(props) {
super(props);
this.state = {
show: false
};
this._onClick = this._onClick.bind(this);
this._dismiss = this._dismiss.bind(this);
}
_onClick(e) {
e.preventDefault();
this.setState({
show: true
})
}
_dismiss() {
this.setState({
show: false
}, function () {
console.log(this.state) // logs: Object {show: true}
})
}
render() {
return (
<div onClick={this._onClick} className="message">
<Modal show={this.state.show} close={this._dismiss}>
<h1>...</h1>
</Modal>
</div>
);
}
}
Modal.jsx
export default class Modal extends React.Component {
constructor(props) {
super(props);
this._onClose = this._onClose.bind(this);
}
_onClose() {
this.props.close()
}
render() {
if (this.props.show) {
return (
<div className="modal" onClick={this._onClose} >
<div className="content">
{this.props.children}
</div>
</div>
);
} else {
return null
}
}
}
Upvotes: 0
Views: 205
Reputation: 2103
The div is still getting on onClick
events event when its children are clicked. I suspect _dismiss
is being called and then _onClick
is being called. React batches setState
calls so it ends up setting show
back to true
.
Remedies.
If the close callback of handler give you the event as an argument. Call e.stopPropagation()
or From @richsilv in the comments e.stopImmediatePropagation()
.
Or if it doesn't pass the event. Check in the _onClick
if show
is true or false. If it is true, don't setState
Upvotes: 3