简体   繁体   English

如何在按钮单击上切换下拉菜单并在外部单击上关闭?

[英]How have toggle dropdown on button click and close on outside click?

I have Dropdown which is open by clicking on button and closed on outside click. 我有下拉菜单,通过单击按钮可以打开,而单击外部按钮则可以关闭。

This is function which toggle dropdown: 这是切换下拉菜单的功能:

toggleAllCategories = () => {
  this.setState({ isOpenAllCategories: !this.state.isOpenAllCategories });
};

That mean by clicking on button you should open and close Dropdown. 这意味着通过单击按钮,您应该打开和关闭下拉菜单。

But in same time I have implemented with react-refs that click outside of body of dropdown ---> close dropdown. 但是在同一时间,我实现了带有react-refs ,该功能在下拉菜单的主体之外单击---> close下拉菜单。

That make bug - reproduction: 那使错误-复制:

Step 1 : Click on "All Categories" btn 步骤1 :点击“所有类别” btn

Result: Dropdown is open 结果:下拉列表处于打开状态

Step 2 : Click again on "All Categories" btn - cus want to close dropdown 步骤2 :再次点击“所有类别” btn-想要关闭下拉菜单

Result: As result Dropdown is open. 结果:结果下拉列表打开。

  1. Clicked on "All categories" btn (state is changed isOpenAllCategories = true) 单击“所有类别” btn(状态更改为isOpenAllCategories = true)

HERE is the problem --> 2. Click Again on "All Categories" btn 这里是问题-> 2.再次单击“所有类别” btn

  • First is called handleOutsideClick() function which sets isOpenAllCategories on false . 首先称为handleOutsideClick()函数,该函数将isOpenAllCategories on false设置isOpenAllCategories on false

  • Then is called toggleAllCategories() which change state on oposite of current value isOpenAllCategories: !this.state.isOpenAllCategories and that is true cus handleOutsideClick() already change state on false . 然后称为toggleAllCategories() ,它根据当前值isOpenAllCategories: !this.state.isOpenAllCategories来更改状态isOpenAllCategories: !this.state.isOpenAllCategories且为truehandleOutsideClick()已更改为false状态。

How have toggle dropdown on button click and close on outside click? 如何在按钮单击上切换下拉菜单并在外部单击上关闭?

All Categories Dropdown component: 所有类别下拉菜单组件:

class AllCategories extends Component {

  componentDidMount() {
    document.addEventListener('mousedown', (e) => this.handleClickOutside(e));
  }

  componentWillUnmount() {
    document.removeEventListener('mousedown', (e) => this.handleClickOutside(e));
  }

  setWrapperRef(node) {
    this.wrapperRef = node;
  }

  handleClickOutside = (event) => {
    if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
      this.props.closeAllCategories();
    }
  };

  render() {
    return (
      <div className="all-categories-wrapper">
        <div className="all-categories" ref={(node) => this.setWrapperRef(node)}>
          <ul className="all-categories-list">
            <li className="all-categories-list-item">All Categories</li>
            {this.state.allCategories.map((category) => (
              <li
                className={`all-categories-list-item ${
                  category.selected ? 'all-categories-list-item-active' : ''
                }`}
              >
                {category.name}
              </li>
            ))}
          </ul>
        </div>
      </div>
    );
  }
}

All Categories Button component: 所有类别按钮组件:

export default ({ toggleAllCategories, className }) => (
  <div className="category" onClick={() => toggleAllCategories()} role="button">
    <div className={`category-button-wrapper ${className}`}>
      <button className="category-button">
        Sports <span className="category-button-slash">/</span> Football
      </button>
      <div className="category-icon-box">
        <span className="category-icon">
          <i className="material-icons md-30 md-white">expand_more</i>
        </span>
      </div>
    </div>
  </div>
);

Code isn't working because of the scope of this in your component functions. 代码不工作,因为在组件的功能范围。 You'll have to bind your functions in the constructor of your component. 您必须将函数绑定到组件的构造函数中。 Or change your functions to ES6 which will solve the issue 或将您的功能更改为ES6,即可解决问题

//binding
constructor(props){
  super(props)
this.handleClickOutside = this.handleClickOutside.bind(this);
}
handleClickOutside = () => {
 //code here
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM