HandleClick внутри и снаружи элемента DOM - PullRequest
0 голосов
/ 28 апреля 2020

Я хочу закрыть меню, когда есть щелчок по <Burger /> и когда есть щелчок снаружи <Burger />. С моим текущим кодом будет обрабатываться только щелчок снаружи <Burger />, но нажатие <Burger /> не закроет меню.

Когда я переворачиваю domNode на !domNode в функции handleClickOutside щелчок внутри <Burger /> работает, но нажатие снаружи <Burger /> больше не закрывает меню. Также я попытался добавить другие условия к функции handleClickOutside, и это тоже не сработало.

Что мне не хватает?

Спасибо!

export class NavBar extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            change: false
        };
        this.handleClick = this.handleClick.bind(this);

        this.handleClickOutside = this.handleClickOutside.bind(this);
    }
    
    componentDidMount() {
        document.addEventListener('click', this.handleClickOutside, true);
    }
    componentWillUnmount(){
        document.removeEventListener('click', this.handleClickOutside, true)
    }

    handleClick() {
        this.setState(state => ({
            change: !state.change
        }));
    }

    handleClickOutside(event) {
        const domNode = ReactDOM.findDOMNode(this);

        if(domNode || !domNode.contains(event.target)){
            this.setState(state=> ({
                change: false
            }))
        }
    }

    render() {
        return (
            <div>
                <div className="mobile">
                    <Menu change={this.state.change} onClickOutside={this.handleClickOutside} />
                    <nav>
                        <Burger change={this.state.change} onClick={this.handleClick} />
                    </nav>
                </div>
            </div>   
        )
    }
}
<Burger />

export class Burger extends React.Component {  
    render(){
        return(
                <a className={classnames('burger', {'change': this.props.change})} onClick={this.props.onClick}> 
                    <div/>
                    <div/>
                    <div/>
                </a>
            
        )
    }
}
<Menu />

export class Menu extends React.Component {
    render(){
        return(
        <div className={classnames({change: !this.props.change})}>
                <div className="menu" onClick={this.props.onClickOutside}>
                    <Link> 
                    </Link>
                   <Link>
                    </Link>
                </div>
        </div>
        )
    }
}

1 Ответ

0 голосов
/ 28 апреля 2020

Я не могу быть уверен, поскольку у меня нет всего вашего кода, но у меня есть предположение.
Вы добавили прослушиватель событий в componentDidMount:

componentDidMount() {
  document.addEventListener('click', this.handleClickOutside, true);
}

С этим кодом, в зависимости от того, как Burger обрабатывает свои onClick реквизиты, это может произойти:

  1. Вы щелкаете внутри Burger; его onClick запускается, что вызывает props.onClick, и поэтому вы вызываете handleClick из NavBar;
  2. Затем, поскольку событие распространяется, оно достигает handleClickOutside, и это потому, что событие достиг document. Итак, поскольку вы звоните handleClickOutside, внутри него вы снова переключаете состояние.

Опять же, это все мое предположение. Если вы хотите проверить это, вы можете использовать отладку и заметить, если при нажатии внутри Burger вы достигнете onClick и handleClickOutside.

В любом случае, будет признателен код обоих Burger и Menu, потому что мы не можем знать, что там происходит.

...