click anywhere to close dropdown in react
My suggestion is that you use the synthetic events onFocus
and onBlur
to trigger open/close state. onFocus
will trigger when the element is clicked and onBlur
will trigger when "unfocusing" (clicking outside). See docs.
Also tabIndex
attribute/prop is needed for focus/blur to work on non input type elements.
I can recommend looking at the source of react-select and how they handle focusing/bluring.
Here is an example, you can see a demo of it here
import React from "react";
class Dropdown extends React.Component {
state = {
open: false
};
toggleDropdown() {
this.setState({ open: !this.state.open });
}
render() {
return (
<div
style={{ border: "1px solid #CCC" }}
onBlur={() => this.toggleDropdown()}
onFocus={() => this.toggleDropdown()}
tabIndex="0"
>
Dropdown
{this.state.open && (
<div>
<div>Red</div>
<div>Green</div>
<div>Blue</div>
</div>
)}
</div>
);
}
}
export default Dropdown;
You could use the react-onclickoutside library that abstracts the body event handling for you. You just have to wrap your component in their onClickOutside
higher order component that will execute the handleClickOutside
callback any time the click happens outside of the drop down. That way you can have a private "open" state in all dropdowns and don't care about how the handling is achieved.
The code might look like that:
import React, { Component } from 'react'
import onClickOutside from 'react-onclickoutside'
class Dropdown extends Component {
constructor() {
this.state = {open: false}
}
// Method automatically executed by the library.
handleClickOutside() {
this.setState({open: false})
}
render() { ... }
}
export default onClickOutside(Dropdown)