2016-12-06 192 views
1

我正在尝试使用反应组件将className添加到div。这是我的。我很新,反应,顺便说一句。无法获取onMouseEnter来更改react.js中的状态

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

对于中有三元条件,如果我把它作为this.state.condition股利则"dropdown-content"的类名显示出来。当我将其更改为!this.state.condition时,显示类名"dropdown-content show"。这意味着我遇到的问题是改变状态。在我的onMouseEnterHandler()函数中,我已经改变了条件为真。依然没有。

我该怎么办?另外,如果我误解了我的问题,任何编辑建议表示赞赏。

+0

如果你把的console.log在'onMouseEnterHandler'它曾经记录它正在被触发? – finalfreq

+0

'onMouseEnterHandler'绑定到正确的上下文吗? –

回答

2

您需要将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> 
    ); 
    } 
} 

见相关阵营文件位置:https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding

+0

丹尼尔,谢谢!我会查看文件并检查绑定。 – Robby

+1

值得注意的是,这适用于您想要作为事件回调调用的任何方法(单击,鼠标输入,窗口大小调整,按键等)。您应该[几乎] _always_将这些回调绑定到他们的实例。很多时候,你会看到开发人员使用一组函数名,这些函数名在构造过程中应该被绑定......类似这样的:'['handleClick','someOtherFunction']。forEach(fn => this [fn] = this [fn] .bind(this));' –

+0

嗨Ryan,谢谢你的提示。当我想调用方法作为事件回调时,我会注意。 – Robby