Change the state when clicking outside a component in React

十年热恋 提交于 2021-01-21 08:45:49

问题


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 component: https://jsbin.com/cunakejufa/edit?js,output


回答1:


You could try leveraging onBlur:

<i onClick={...} onBlur={() => this.setState({showingProjectSelector: false})}/>



回答2:


I faced same issue with you. Solved after reading this: Detect click outside React component Please try:




回答3:


You should use a High Order Component to wrap the component that you would like to listen for clicks outside it.

This component example has only one prop: "onClickedOutside" that receives a function.

ClickedOutside.js
import React, { Component } from "react";

export default class ClickedOutside extends Component {
  componentDidMount() {
    document.addEventListener("mousedown", this.handleClickOutside);
  }

  componentWillUnmount() {
    document.removeEventListener("mousedown", this.handleClickOutside);
  }

  handleClickOutside = event => {
    // IF exists the Ref of the wrapped component AND his dom children doesnt have the clicked component 
    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 component
    // Because it wouldn't work if use a functional component (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>;
  }
}



回答4:


If you want to use a tiny component (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 component and inside of another. It also supports detecting other types of events.

Using the library you can have something like this inside your component.

import OnOutsiceClick from 'react-outclick';

class MyComp extends Component { 

  render() {
    return (
      <OnOutsiceClick
        onOutsideClick={() => this.setState({showingProjectSelector: false})}>
        <Dropdown />
      </OnOutsiceClick>
    );
  }
}


来源:https://stackoverflow.com/questions/48674246/change-the-state-when-clicking-outside-a-component-in-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!