【问题标题】:Can't get onMouseEnter to change state in react.js无法让 onMouseEnter 更改 react.js 中的状态
【发布时间】:2016-12-06 16:39:39
【问题描述】:

我正在尝试使用反应组件将类名添加到 div。这就是我所拥有的。顺便说一句,我对反应还很陌生。

class PrimaryNavigation extends Component {

  constructor(props) {
    super(props);

    this.state = {
      condition: false
    };
  }

  onMouseEnterHandler() {
    this.setState({
      condition: !this.state.condition
    });
  }

  clickHandlerFor(component) {
    return (e) => {
      if (typeof this.props.onClick !== 'function') {
        return;
      }
      e.preventDefault();
      var componentData = this.componentDataFor(component);
      this.props.onClick(e, componentData);
    };
  }

  componentDataFor(component) {
    ...
  }

  render(): ReactElement {
    ...
    return (
      <div className='PrimaryNavigation'>
        <nav className='PrimaryNavigation-Links'>
          <ul>
            ...
            <li className="dropdown" onMouseEnter={this.onMouseEnterHandler}>
              <Link to='/account' className='PrimaryNavigation-link dropbtn'>
                <span className='PrimaryNavigation-label'><FormattedMessage id='navigation.my_account' /></span>
              </Link>
              <div id="myDropdown" className={this.state.condition ? "dropdown-content show" : "dropdown-content" }>
                <div className="dropdown-box">
                ...
                </div>
              </div>
            </li>

          </ul>
        </nav>
      </div>
    );
  }
}

对于其中包含三元条件的 div,如果我将其保留为 this.state.condition,则 "dropdown-content" 的类名会出现。当我将其更改为!this.state.condition 时,"dropdown-content show" 的类名就会出现。意思是我遇到的问题是改变状态。在我的onMouseEnterHandler() 函数中,我已将条件更改为真。依然没有。

我能做什么?此外,如果我的问题措辞不正确,欢迎提出任何编辑建议。

【问题讨论】:

  • 如果您在onMouseEnterHandler 中放置一个console.log,它是否会记录它正在被触发?
  • onMouseEnterHandler 是否绑定到正确的上下文?

标签: javascript reactjs


【解决方案1】:

您需要在构造函数中将onMouseEnterHandler() 方法绑定到组件实例,否则this 上下文将不是组件并且setState() 将未定义。查看更新的代码:

class PrimaryNavigation extends Component {

  constructor(props) {
    super(props);

    this.state = {
      condition: false
    };

    this.onMouseEnterHandler = this.onMouseEnterHandler.bind(this);
  }

  onMouseEnterHandler() {
    this.setState({
      condition: !this.state.condition
    });
  }

  clickHandlerFor(component) {
    return (e) => {
      if (typeof this.props.onClick !== 'function') {
        return;
      }
      e.preventDefault();
      var componentData = this.componentDataFor(component);
      this.props.onClick(e, componentData);
    };
  }

  componentDataFor(component) {
    ...
  }

  render(): ReactElement {
    ...
    return (
      <div className='PrimaryNavigation'>
        <nav className='PrimaryNavigation-Links'>
          <ul>
            ...
            <li className="dropdown" onMouseEnter={this.onMouseEnterHandler}>
              <Link to='/account' className='PrimaryNavigation-link dropbtn'>
                <span className='PrimaryNavigation-label'><FormattedMessage id='navigation.my_account' /></span>
              </Link>
              <div id="myDropdown" className={this.state.condition ? "dropdown-content show" : "dropdown-content" }>
                <div className="dropdown-box">
                ...
                </div>
              </div>
            </li>

          </ul>
        </nav>
      </div>
    );
  }
}

在此处查看相关的 React 文档:https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding

【讨论】:

  • 丹尼尔,谢谢!我会查看文件并检查装订。
  • 值得注意的是,这适用于您想作为事件回调调用的任何方法(单击、鼠标进入、窗口调整大小、按键等)。您应该[几乎]总是将这些回调绑定到它们的实例。很多时候你会看到开发人员使用了一个函数名数组,这些函数名应该在构造过程中被绑定......就像这样:['handleClick', 'someOtherFunction'].forEach(fn =&gt; this[fn] = this[fn].bind(this));
  • 嗨,瑞恩,感谢您的来信。当我想调用一个方法作为事件回调的时候我会注意的。
猜你喜欢
  • 1970-01-01
  • 2015-04-13
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
  • 2018-02-19
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
相关资源
最近更新 更多