最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Change the state when clicking outside a component in React - Stack Overflow

programmeradmin3浏览0评论

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
Add a ment  | 

5 Answers 5

Reset to default 6

You 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.

发布评论

评论列表(0)

  1. 暂无评论