[英]Hide dropdown menu upon clicking outside of it
我在 React 應用程序中實現的下拉菜單有問題。
下拉列表基於這篇文章: https : //blog.campvanilla.com/reactjs-dropdown-menus-b6e06ae3a8fe
打開和關閉下拉菜單可以正常工作,但是當我單擊菜單中的按鈕時,出現以下錯誤:
TypeError: Cannot read property 'contains' of null
回到博客,看到其他人在評論中也報告了同樣的錯誤:
好一個。 但只是最后一部分不起作用。 dropDownMenu 保持“空”
一種可能的解決方案是將current
添加到以下代碼行:
if (!this.dropdownMenu.contains(event.target)) {
if (!this.dropdownMenu.current.contains(event.target)) {
我在 StackOverflow 上找到了一個類似的答案,其中另一個用戶遇到了下拉菜單的問題: Cannot read property 'addEventListener' of null on menu但我仍然無法找出錯誤。
import React, { Component } from 'react';
import {Link, withRouter} from 'react-router-dom'
import logo from '../images/logo.svg'
import Settings from '../lotties/Settings'
class InnerHeader extends Component {
constructor() {
super();
this.state = {
showMenu: false,
fade: false
};
this.showMenu = this.showMenu.bind(this);
this.closeMenu = this.closeMenu.bind(this);
}
showMenu(event) {
event.preventDefault();
this.setState({ showMenu: true }, () => {
document.addEventListener('click', this.closeMenu);
});
}
closeMenu(event) {
if (!this.dropdownMenu.current.contains(event.target)) {
this.setState({ showMenu: false }, () => {
document.removeEventListener('click', this.closeMenu);
});
}
}
handleLogout = () => {
localStorage.removeItem('authToken');
this.setState({
currentUser: null
})
this.props.history.push("/")
}
render() {
return (
<>
<div id="inner-header">
<div className="logo">
<Link to="/dashboard"><img src={logo} height="50px" alt="site logo" /></Link>
</div>
<div>
<button
className="menu-button"
onClick={this.showMenu}>
<Settings/>
</button>
<br />
{
this.state.showMenu
? (
<div
className="drop-down fade-in"
ref={(element) => {
this.dropdownMenu = element;
}}
>
<div className="center-it-menu">
<Link to="/account"> Account </Link>
<br />
<Link to="/integrations"> Integrations </Link>
<br />
<Link to="/tutorials"> Tutorials </Link>
<br />
<Link to="/support"> Support </Link>
<br />
<button id="menu-alert" onClick={this.handleLogout}> Logout </button>
</div>
</div>
)
: (
null
)
}
</div>
</div>
</>
)
}
}
export default withRouter(InnerHeader)
由於我仍在學習編程,因此我不想依賴庫來完成這項任務,也不想只是 c&p 一個解決方案。 除了解決方案之外,我想知道是什么導致了這種情況以及如何解決它。 由於它是您在 google react 創建下拉菜單時顯示的第一篇文章之一,因此如果其他人試圖實現這一點,我希望他們有一個很好的答案。
我必須說,根本不需要所描述場景中的 ref 屬性。 要在菜單外部單擊時折疊菜單,您可以使用Element.closest()
方法,該方法將向下遍歷 DOM 樹以在event.target
祖先中查找className="menu"
元素:
const { Component } = React, { render } = ReactDOM class Card extends Component { constructor() { super(); this.state = { showMenu: false, }; this.showMenu = this.showMenu.bind(this); this.closeMenu = this.closeMenu.bind(this); } showMenu(event) { event.preventDefault(); this.setState({ showMenu: true }, () => { document.addEventListener('click', this.closeMenu); }); } closeMenu(event) { if (!event.target.closest('.menu')) { this.setState({ showMenu: false }, () => { document.removeEventListener('click', this.closeMenu); }); } } render() { return ( <div> <button onClick={this.showMenu}> Show menu </button> { this.state.showMenu ? ( <div className="menu" > <button> Menu item 1 </button> <button> Menu item 2 </button> <button> Menu item 3 </button> </div> ) : ( null ) } </div> ); } } render (<Card />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>
這是因為當您不單擊Button 時,此代碼不會執行並且不會啟動this.dropdownMenu因此它是Undefined 。 在這種情況下,您應該使用onChange事件並向其添加一個偵聽器,然后在該函數中執行您想要的任何操作。 願它會幫助你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.