ReactJS:放置在子组件上时onClick处理程序不会触发

时间:2014-06-08 04:42:42

标签: reactjs react-jsx

我最近开始使用ReactJS。具体来说,我正在使用react-rails ruby​​ gem和react-bootstrap组件。

我有一个关于将onClick事件侦听器放在子组件中的问题。

正如您从下面的代码示例中看到的那样,我有一个父组件,可以调用' render函数中的子组件。在render函数中,我有React onClick侦听器,在单击时调用handleToggle

###* @jsx React.DOM ###

ToggleIconButton = React.createClass
  getInitialState: ->
    toggleOn: false
  handleToggle: (evt) ->
    this.setState(toggleOn: !this.state.toggleOn)
  render: ->
    `<IconButton onClick={this.handleToggle}>Toggle Button</IconButton>`

IconButton = React.createClass
  render: ->
    # BsButton and BsGlyphicon are React-Bootstrap components
    `<BsButton>
      <BsGlyphicon glyph={this.props.glyph} />
      {" " + this.props.text}
     </BsButton>`

不幸的是,这并没有像我想象的那样发挥作用。 ToggleIconButton::handleToggle永远不会被调用。相反,onClick侦听器位于IconButton并引用ToggleIconButton::handleToggle

React Dev Tool Screen


我不想向IconButton添加任何其他行为。我看待它的方式,IconButton中不应放置条件逻辑。它应该做的只是代表一个图标和按钮,而不必担心任何浏览器事件。这是ToggleIconButton的用途。

虽然我知道我可以将React Div包裹在IconButton并在那里写一个onClick听众(我已经尝试了这个并且它有效),但似乎是这样的&#39有点janky。

有人知道这样做的好方法吗?谢谢你们!

2 个答案:

答案 0 :(得分:79)

因此,在这种情况下处理事件的正确方法是将事件处理程序传递给子组件。有几种方法可以实现您想要的,我可能会以不同的方式实现此行为(不确定用例是什么),但我在JSX中为您演示了一个示例,演示了父组件和子组件之间的典型事件处理。你可以在这里找到它......

JS Fiddle

想想这样:

var ParentComponent = React.createClass({
    render: function(){
        return (
            <ChildComponent onSomeEvent={this.handleThatEvent} />;
        )
    },
    handleThatEvent: function(e){
         //update state, etc.
    }
});

var ChildComponent = React.createClass({
    render: function(){
        return (
           <input type="button" onClick={this.props.onSomeEvent} value="Click Me!" />
        )
    }
});

答案 1 :(得分:9)

如果您在调用节点之前创建了一个var来引用渲染,那么您不需要制作子组件

var self = this;

所以例如(这是设计的,在这种情况下不需要var self,但是在嵌套的return语句的情况下,它是必需的。)

var ParentComponent = React.createClass({
    render: function(){
        var self = this;
        return (
            <input type="button" onClick={self.handleThatEvent} value="Click Me!" />;
        )
    },
    handleThatEvent: function(e){
         //update state, etc.
    }
});

更好的是,你可以将它绑定到函数。

var ParentComponent = React.createClass({
    render: function(){
        return (
            this.state.array.map(function(){
              return (<input type="button" onClick={this.handleThatEvent} value="Click Me!" />);
            }.bind(this));
        )
    },
    handleThatEvent: function(e){
         //update state, etc.
    }
});

或者在评论中关注captray的建议

var ParentComponent = React.createClass({
    render: function(){
        return (
            this.state.array.map(function(){
              return (<input type="button" onClick={this.handleThatEvent} value="Click Me!" />);
            }, this);
        )
    },
    handleThatEvent: function(e){
         //update state, etc.
    }
});