简体   繁体   中英

Why does State remains unchanged after setState

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
        }
    }
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM