【问题标题】:React onClick state is not toggling backReact onClick 状态没有切换回来
【发布时间】:2016-08-17 17:28:26
【问题描述】:

我正在使用 React JS 构建一个菜单栏。单击菜单项时,应打开相应的 megamenu。在 megamenu 外部单击时,它应该自行关闭。我通过切换 megamenu 的状态来弥补这一点。但是我也想在第二次单击菜单项时关闭 megamenu(即通过单击菜单项来切换关闭和打开 megamenu)。我被困在这里,第二次单击菜单项时,状态没有切换回来。

class Menubar extends React.Component {
  constructor() {
    super();
    this.state = {
      clicked: false
    };
    this.handleClick = this.handleClick.bind(this);
    this.handleOutsideClick = this.handleOutsideClick.bind(this);
  }

  componentWillMount() {
    document.addEventListener('click', this.handleOutsideClick, false);
  }

  componentWillUnmount(){
    document.removeEventListener('click', this.handleOutsideClick, false);
  }

  handleClick() {
    this.setState({clicked: !this.state.clicked});
  }

  handleOutsideClick(){
    if (this.refs.megaMenu.contains(event.target)) {
      } else {
        this.setState({
          clicked: false
        });
      }
   }

   render() {
    return (
      <div className="container">
        <div className="menu-bar">
          {/* Menu*/}
          <div className="menu-bar-item">
            <a className="menu-bar-link" href="#" onClick={this.handleClick}>Points</a>
            <div className={"mega-menu"+" "+this.state.clicked} ref="megaMenu">
              <div className="mega-menu-content">
                <p>Points Menu</p>
              </div>
            </div>
          </div>
        </div>
      </div>
     );
   }
}

ReactDOM.render(
  <Menubar />,
  document.getElementById('example')
);

Codepen Demo

【问题讨论】:

    标签: javascript html reactjs


    【解决方案1】:

    您需要移动ref="megaMenu",因此它也包含按钮,否则当您单击按钮时handleOutsideClick 也会被触发并且您翻转this.state.clicked 两次。另外,您忘记在handleOutsideClick 处理程序中传递event

    class Menubar extends React.Component {
      constructor() {
        super();
        this.state = {
          clicked: false
        };
        this.handleClick = this.handleClick.bind(this);
        this.handleOutsideClick = this.handleOutsideClick.bind(this);
      }
    
      componentWillMount() {
        document.addEventListener('click', this.handleOutsideClick, false);
      }
    
      componentWillUnmount() {
        document.removeEventListener('click', this.handleOutsideClick, false);
      }
    
      handleClick() {
        this.setState({clicked: !this.state.clicked});
      }
    
      handleOutsideClick(event) {
        if (!this.menu.contains(event.target)) {
          this.setState({
            clicked: false
          });
        }
      }
    
      render() {
        return (
          <div className="container">
            <div className="menu-bar">
    
              {/* Menu*/}
              <div className="menu-bar-item" ref={el => this.menu = el}>
                <a className="menu-bar-link" href="#" onClick={this.handleClick}>Points</a>
                <div className={"mega-menu" + " " + this.state.clicked}>
                  <div className="mega-menu-content">
                    <p>Points Menu</p>
                  </div>
                </div>
              </div>
    
            </div>
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <Menubar />,
      document.getElementById('example')
    );
    

    我已经修复了你的Codepen Demo

    另外,考虑使用像ref={el =&gt; this.menu = el}这样的回调引用 这是一种更好的方法。

    【讨论】:

    • 谢谢你用你的回答解释我的错误:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 2020-04-29
    • 2019-10-17
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    相关资源
    最近更新 更多