Most of the time, your components respond to events that occur within the component tree by defining their own handler or by accepting a handler defined by a parent component via props. Sometimes, this isn't enough. In this lesson, we'll rely on lifecycle hooks and good old fashioned DOM events to update state in a React component in response to an event that occurs outside of the component tree.

class Menu extends React.Component {
constructor(props) {
super(props)
this.state = {
isVisible: false
}
this.handleClickOutside = this.handleClickOutside.bind(this)
this.toggleOptions = this.toggleOptions.bind(this)
this.handleClick = this.handleClick.bind(this)
}
componentDidMount() {
document.addEventListener('click', this.handleClickOutside)
} componentWillUnmount() {
document.removeEventListener('click', this.handleClickOutside)
} handleClickOutside(evt) {
if (!this.node.contains(evt.target)) {
this.setState({ isVisible: false })
}
} toggleOptions(evt) {
evt.preventDefault()
this.setState(state => ({ isVisible: !state.isVisible }))
} handleClick(choice, evt) {
evt.preventDefault()
this.props.handleMenuChoice(choice)
this.setState({ isVisible: false })
} render() {
return (
<div className="menu" ref={el => (this.node = el)}>
<a href="#" onClick={this.toggleOptions}>
Options
</a>
{this.state.isVisible
? <div className="menuContents">
<a href="#" onClick={this.handleClick.bind(null, 'one')}>
One
</a>
<a href="#" onClick={this.handleClick.bind(null, 'two')}>
Two
</a>
<a href="#" onClick={this.handleClick.bind(null, 'three')}>
Three
</a>
<a href="#" onClick={this.handleClick.bind(null, '')}>
Clear Selection
</a>
</div>
: null}
</div>
)
}
}

The most important thing is how to detect whether user click outside the menu or not.

To do that, we use 'ref':

<div className="menu" ref={el => (this.node = el)}>

We assign the elememt to vairable 'this.node'.

console log the node:

<div class="menu">
<a href="#">options</a>
</div>

When we click inside the menu, the 'evt.target' is the 'a' tag.

If we click outside the menu, then then 'evt.target' is the whole html tag.

Therefore, we can check:

if (!this.node.contains(evt.target)) {

[React] Close the menu component when click outside the menu的更多相关文章

  1. React.createClass和extends Component的区别

    React.createClass和extends Component的区别主要在于: 语法区别 propType 和 getDefaultProps 状态的区别 this区别 Mixins 语法区别 ...

  2. React Native 中的component 的生命周期

    React Native中的component跟Android中的activity,fragment等一样,存在生命周期,下面先给出component的生命周期图 getDefaultProps ob ...

  3. React 的 PureComponent Vs Component

    一.它们几乎完全相同,但是PureComponent通过prop和state的浅比较来实现shouldComponentUpdate,某些情况下可以用PureComponent提升性能 1.所谓浅比较 ...

  4. 【转】Pro Android学习笔记(三十):Menu(1):了解Menu

    目录(?)[-] 创建Menu MenuItem的属性itemId MenuItem的属性groupId MenuItem的属性orderId MenuItem的属性可选属性 Menu触发 onOpt ...

  5. [React Native] Create a component using ScrollView

    To show a list of unchanging data in React Native you can use the scroll view component. In this les ...

  6. [React] Write a stateful Component with the React useState Hook and TypeScript

    Here we refactor a React TypeScript class component to a function component with a useState hook and ...

  7. [React] Refactor a Class Component with React hooks to a Function

    We have a render prop based class component that allows us to make a GraphQL request with a given qu ...

  8. 关于React的Container&Presentational Component模型结构分析

    react.js javascript 3 之前翻译了两篇关于Container&Presentational Component模型的文章,一篇是基础的Container和Component ...

  9. [React Router v4] Use the React Router v4 Link Component for Navigation Between Routes

    If you’ve created several Routes within your application, you will also want to be able to navigate ...

随机推荐

  1. 《linux 内核全然剖析》编译linux 0.12 内核 Ubuntu 64bits 环境

    我×.. . 最终好了,大概3 4个小时吧...各种毛刺问题.终究还是闯过来了.. .. ubuntu2@ubuntu:~/Downloads/linux-0.00-050613/linux-0.00 ...

  2. HDOJ 5414 CRB and String 模拟

    CRB and String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) T ...

  3. 高效的TCP数据拆包器

    高效的TCP数据拆包器 接收器,每秒拆1KB的包达到30万以上 /// 数据同步协义数据接收器 /// </summary> /// <remarks> /// 主要功能有 / ...

  4. eclipse的项目栏

    点击window然后选择show view 然后选择project Explorer就会出现项目栏

  5. Android框架之路——OkGo的使用

    一.简介 该库是封装了okhttp的标准RESTful风格的网络框架,可以与RxJava完美结合,比Retrofit更简单易用.支持大文件上传下载,上传进度回调,下载进度回调,表单上传(多文件和多参数 ...

  6. [log4j]Slf4j的包冲突

    Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.log4j.Log4jLoggerFa ...

  7. 原生JS实现页面内定位

    需求:点击跳转到页面指定位置 <div id="test">点击跳转到此处</div> [法一]: 利用a标签的锚点跳转 <a href=" ...

  8. JavaScript翻译成Java

    这两天公司有一个需求,将一段加密的JavaScript代码转换为JAVA版. JavaScript中的某一段代码: 前期查看了整个JavaScript代码,发现代码中,方法里面嵌套方法,各种不合规的变 ...

  9. lunix 命令积累

    .修改文件的拥有者 chown 用户:用户 文件 .切换账号 su 账号 . 追踪路由信息 traceroute 主机名

  10. 一起talk C栗子吧(第三十四回:C语言实例--巧用溢出计算最值)

    各位看官们.大家好,上一回中咱们说的是巧用移位的样例,这一回咱们说的样例是:巧用溢出计算最值. 闲话休提,言归正转.让我们一起talk C栗子吧! 大家都知道,程序中的变量都有一个取值范围,这个范围也 ...