简体   繁体   中英

Can't get onMouseEnter to change state in react.js

I'm trying to add a className to a div using react components. This is what I have. I'm fairly new to react, btw.

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>
    );
  }
}

For the div that has the ternary condition in it, if I keep it as this.state.condition then the className of "dropdown-content" shows up. When I change it to !this.state.condition then the classname of "dropdown-content show" shows up. meaning the issue I'm having is changing the state. in my onMouseEnterHandler() function I have changed condition to being true. Still nothing.

What can I do? Also, if i've phrased my question incorrectly, any edit suggestions is appreciated.

You need to bind the onMouseEnterHandler() method to the component instance in your constructor, otherwise the this context won't be the component and setState() will be undefined. See updated code:

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>
    );
  }
}

See relevant React documentation here: https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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