0

我有下拉菜单,应该关闭 onSelect 项目下拉菜单。

这是被调用onSelect但认为状态isOpen: false不会改变的函数,

但是状态部分:selected: option将被更改。

有谁知道为什么?

onSelect = (option) => {
    this.setState({ selected: option, isOpen: false }, () => {
      this.props.onSelect(option);
    });
  };

这是一个完整的组件:

import React from 'react';
import onClickOutside from 'react-onclickoutside';

class SimpleDropdown extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      selected: props.selectValue,
      isOpen: false
    };
  }

  toggleDropdown = () => {
    // eslint-disable-next-line react/no-access-state-in-setstate
    this.setState({ isOpen: true });
  };

  onSelect = (option) => {
    this.setState({ selected: option, isOpen: false }, () => {
      this.props.onSelect(option);
    });
  };

  handleClickOutside = () => {
    this.setState({ isOpen: false });
  };

  render() {
    const { selected } = this.state;
    const { title, isLoading } = this.props;

    return (
      <div className="simple-dropdown" onClick={this.toggleDropdown} role="button">
        <span className="dropdown-title">{title}:</span>
        <span>{selected.value}</span>
        {this.state.isOpen && !isLoading && (
          <ul className="dropdown-ul">
            {this.props.options.map((option) => (
              <li
                key={option.key}
                className={`dropdown-option ${option.value === selected.value ? 'hover' : ''}`}
              >
                <a className="option-btn" onClick={() => this.onSelect(option)} role="button">
                  {option.value}
                </a>
              </li>
            ))}
          </ul>
        )}
      </div>
    );
  }
}

export default onClickOutside(SimpleDropdown);
4

2 回答 2

1

this.toggleDropdown即使在选择值时也会被触发,所以添加这样的检查

toggleDropdown = () => {
    // eslint-disable-next-line react/no-access-state-in-setstate
    if (!this.state.isOpen) {
      this.setState({ isOpen: true });
    }
    
  };

于 2020-01-20T22:56:41.817 回答
1

这是由Event bubbling一种事件传播引起的。
基本上子元素的点击事件会触发父元素的点击事件。您可以通过调用event.stopPropagation()子元素单击处理程序来解决此问题。

注意下面onClick的处理程序。处理程序正在获取event对象,然后调用stopPropagation方法。

<li
  key={option.key}
  className={`dropdown-option ${option.value === selected.value ? 'hover' : ''}`}
>
  <a className="option-btn" onClick={(event) => {event.stopPropagation(); this.onSelect(option)}} role="button">
                  {option.value}
  </a>
</li>
于 2020-01-20T23:39:11.980 回答