I have a dropdown as is shown in the following image:
When I click the folder icon it opens and closes because showingProjectSelector
property in the state that is set to false.
constructor (props) {
super(props)
const { organization, owner, ownerAvatar } = props
this.state = {
owner,
ownerAvatar,
showingProjectSelector: false
}
}
When I click the icon, it opens and closes properly.
<i
onClick={() => this.setState({ showingProjectSelector: !this.state.showingProjectSelector })}
className='fa fa-folder-open'>
</i>
But what I'm trying to do is to close the dropdown when I click outside it. How can I do this without using any library?
This is the entire ponent: ,output
I have a dropdown as is shown in the following image:
When I click the folder icon it opens and closes because showingProjectSelector
property in the state that is set to false.
constructor (props) {
super(props)
const { organization, owner, ownerAvatar } = props
this.state = {
owner,
ownerAvatar,
showingProjectSelector: false
}
}
When I click the icon, it opens and closes properly.
<i
onClick={() => this.setState({ showingProjectSelector: !this.state.showingProjectSelector })}
className='fa fa-folder-open'>
</i>
But what I'm trying to do is to close the dropdown when I click outside it. How can I do this without using any library?
This is the entire ponent: https://jsbin./cunakejufa/edit?js,output
Share Improve this question edited Feb 7, 2018 at 22:40 Lizz Parody asked Feb 7, 2018 at 22:21 Lizz ParodyLizz Parody 1,76513 gold badges31 silver badges50 bronze badges 4- stackoverflow./questions/32553158/… – Andrew Li Commented Feb 7, 2018 at 22:24
- 1 github./Pomax/react-onclickoutside – mu_sa Commented Feb 7, 2018 at 22:31
- I have used this package in multiple projects and it works flawlessly: npmjs./package/react-onclickoutside – Chase DeAnda Commented Feb 7, 2018 at 22:31
- Hope this helps stackblitz./edit/react-vzhmj7 I did for popover, use like this in your scenario – Jayavel Commented Feb 9, 2018 at 7:35
5 Answers
Reset to default 6You could try leveraging onBlur
:
<i onClick={...} onBlur={() => this.setState({showingProjectSelector: false})}/>
I faced same issue with you. Solved after reading this: Detect click outside React ponent Please try:
You should use a High Order Component to wrap the ponent that you would like to listen for clicks outside it.
This ponent example has only one prop: "onClickedOutside" that receives a function.
ClickedOutside.js
import React, { Component } from "react";
export default class ClickedOutside extends Component {
ponentDidMount() {
document.addEventListener("mousedown", this.handleClickOutside);
}
ponentWillUnmount() {
document.removeEventListener("mousedown", this.handleClickOutside);
}
handleClickOutside = event => {
// IF exists the Ref of the wrapped ponent AND his dom children doesnt have the clicked ponent
if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
// A props callback for the ClikedClickedOutside
this.props.onClickedOutside();
}
};
render() {
// In this piece of code I'm trying to get to the first not functional ponent
// Because it wouldn't work if use a functional ponent (like <Fade/> from react-reveal)
let firstNotFunctionalComponent = this.props.children;
while (typeof firstNotFunctionalComponent.type === "function") {
firstNotFunctionalComponent = firstNotFunctionalComponent.props.children;
}
// Here I'm cloning the element because I have to pass a new prop, the "reference"
const children = React.cloneElement(firstNotFunctionalComponent, {
ref: node => {
this.wrapperRef = node;
},
// Keeping all the old props with the new element
...firstNotFunctionalComponent.props
});
return <React.Fragment>{children}</React.Fragment>;
}
}
If you want to use a tiny ponent (466 Byte gzipped) that already exists for this functionality then you can check out this library react-outclick.
The good thing about the library is that it also lets you detect clicks outside of a ponent and inside of another. It also supports detecting other types of events.
Using the library you can have something like this inside your ponent.
import OnOutsiceClick from 'react-outclick';
class MyComp extends Component {
render() {
return (
<OnOutsiceClick
onOutsideClick={() => this.setState({showingProjectSelector: false})}>
<Dropdown />
</OnOutsiceClick>
);
}
}
Wrapper ponent - i.e. the one that wrapps all other ponents
create onClick event that runs a function handleClick.
handleClick function checks ID of the clicked event.
When ID matches it does something, otherwise it does something else.
const handleClick = (e) => {
if(e.target.id === 'selectTypeDropDown'){
setShowDropDown(true)
} else {
setShowDropDown(false);
}
}
So I have a dropdown menu that appears ONLY when you click on the dropdown menu, otherwise it hides it.