javascript 当函数传递给子级时,反应 onClick 事件不会触发

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32642409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 15:33:01  来源:igfitidea点击:

React onClick event not firing when function is passed to child

javascriptreactjsecmascript-6

提问by BenM

I have a pretty simple React component where I pass the callback for the onClickevent to a child element; however, the onClick event does not seem to ever fire. The class is below, HamburgerMenuand Hamburgerare correctly imported/rendered with no events existing on those components.

我有一个非常简单的 React 组件,我将onClick事件的回调传递给子元素;但是, onClick 事件似乎永远不会触发。该类在下面,HamburgerMenu并且Hamburger在这些组件上不存在任何事件的情况下正确导入/呈现。

export default class AppHandler extends React.Component {
  componentWillMount() {
    this.state = {
      menuOpen: false
    };
  }
  render() {
    return (
      <div>
        <HamburgerMenu menuOpen={this.state.menuOpen} />
        <div className="content">
          <nav>
            <Hamburger onClick={this.onMenuChange.bind(this)} />
          </nav>
        </div>
      </div>
    );
  }
  onMenuChange() {
    console.log('onMenuChanged');
    this.setState({ menuOpen: !this.menuOpen });
  }
};

I can get it to work if in the Hamburgercomponent I set another onClickevent on the root element and then set this.props.onClickas that event handler but that seems like it's unnecessary from everything I have saw.

如果在Hamburger组件中我onClick在根元素上设置另一个事件,然后设置this.props.onClick为该事件处理程序,我可以让它工作,但从我所看到的一切来看,这似乎是不必要的。

Any guidance? Thank you!

任何指导?谢谢!

回答by BenM

So this did end up being me not understanding where the onClickevent is getting attached. Since the component itself is not really an actual element when setting onClick={this.onMenuChange(this)}I am only setting prop.onClickfor the child element Hamburger. In order to actually get the bind to work I dohave to set onClick={this.props.onClick}on the root element of the Hamburgercomponent.

所以这最终让我不明白onClick事件是从哪里开始的。由于组件本身在设置onClick={this.onMenuChange(this)}时并不是真正的实际元素,因此我只prop.onClick为子元素设置Hamburger。为了真正获得绑定到工作,我必须设置onClick={this.props.onClick}的根元素Hamburger组成。

回答by TIJ

You don't need to bind thiswhen you are using component, It's enough to bind thisin your <Hamburger />component. Please see the following sample code

this使用组件时不需要绑定,在你的组件中绑定this就可以了<Hamburger />。请看下面的示例代码

import React from 'react';
import Button from 'components/Button';

class App extends React.Component {
  handleClick(e){
    console.log(e.target);
  }

  render(){
    return (
      <Button Text="Save" onClick={this.handleClick} />
    );
  }
}

//Button Component
class Button extends React.Component {
  clickEventHandler(e) {
      this.props.onClick(e);
  }
  render(){
    return (
      <button onClick="this.clickEventHandler.bind(this)">{this.props.Text}</button>
    );
  }
}

回答by Josh Beam

Since you're exporting an ES6 class and not using createClass, you have to bind handlers to this:

由于您要导出 ES6 类而不是使用createClass,您必须将处理程序绑定到this

<Hamburger onClick={this.onMenuChange.bind(this)} />

See the React docs on no autobindingto ready why:

请参阅有关无自动绑定的 React 文档以准备好原因:

Methods follow the same semantics as regular ES6 classes, meaning that they don't automatically bind this to the instance. You'll have to explicitly use .bind(this) or arrow functions =>.

方法遵循与常规 ES6 类相同的语义,这意味着它们不会自动将 this 绑定到实例。您必须明确使用 .bind(this) 或箭头函数 =>。

Also, you have error with your state. this.setState({ menuOpen: !this.menuOpen });will set this.state.menuOpen, but since you're not mutating the prop, it will never change here: <HamburgerMenu menuOpen={this.menuOpen} />.

此外,您的状态有误。this.setState({ menuOpen: !this.menuOpen });将设置this.state.menuOpen,但由于您没有改变prop,它永远不会在这里改变:<HamburgerMenu menuOpen={this.menuOpen} />

That line should be:

该行应该是:

<HamburgerMenu menuOpen={this.state.menuOpen} />

// and you should set a default state as well

// in AppHandler
componentWillMount() {
  this.state = {
    menuOpen: this.props.menuOpen
  };
}