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

IT技术 reactjs react-jsx
2021-04-15 11:31:32

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

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

从下面的代码示例中可以看出,我有一个父组件,它在其render函数中“调用”了一个子组件在该render函数中,我有 ReactonClick侦听器,可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开发工具屏幕


我不想向IconButton. 在我看来,不应该在IconButton. 它应该做的就是代表一个图标和按钮,而不必担心任何浏览器事件。ToggleIconButton就是为了。

虽然我知道我可以换一个React Div围绕IconButton,写一个onClick监听器那里(我已经试过这和它的作品),似乎这是一个有点janky。

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

2个回答

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

JS小提琴

可以这样想:

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!" />
        )
    }
});
先生,您是对的,我对此进行了掩饰:) 所以,您可以做的是将该组件包装在一个 div 中,并为该 div 注册 onClick 以获得您想要的功能,而不会因该行为而污染 ChildComponent。类似于 <div onClick={this.handleToggle}> <ChildComponent /> </div>
2021-05-27 11:31:32
哇谢谢你!这真的很有帮助:)
2021-05-28 11:31:32
此外,如果没有清楚地将该事件传递给 ChildComponent,您就不能准确地对其调用 onClick,因为 Component 本身并不是真正的 HTML 元素,因此没有为其定义 onClick。
2021-05-31 11:31:32
谢谢!拯救我的一天!:D 不用说,必须注意绑定父组件以获得正确的范围和行为。
2021-05-31 11:31:32
谢谢帽子。正如您从原始帖子中看到的那样,我确实安装了 ReactJS 开发工具:)。虽然我知道在我的子组件中我可以添加一个onClick监听器来调用子组件的函数props,但似乎我不应该这样做......如果子组件不一定有 onClick 监听器怎么办其他情况?如果我想在不同的父组件中使用此组件但没有 onClick 侦听器怎么办?这不会损害组件的可重用性吗?如果这没有意义,请告诉我。
2021-06-04 11:31:32

如果在调用节点之前创建一个 var 来引用渲染的 this ie,则不需要创建子组件

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.
    }
});
试试看。但根据绑定,它将是父母。
2021-05-30 11:31:32
handleThatEvent 有什么作用域?它会有孩子的道具还是父母的道具?
2021-06-05 11:31:32
这很棒!我是 React 的新手,只是将我的应用程序重构为更简单和更优雅......花了一天时间试图找出为什么一些嵌套的 child^parent 调用被破坏了。这(没有双关语意)修复了一切!
2021-06-08 11:31:32
提醒一下,对于那些希望在这种情况下使用 bind 的人......许多函数调用,如 map 和 filter 接受第二个参数,它与 bind 做同样的事情,它将执行上下文设置为传入的内容,所以你可以调用 .map(function(item) { //do stuff }, this);
2021-06-11 11:31:32
太好了,感谢当您有多次退货时,此解决方案有效(在我的情况下为 3)
2021-06-16 11:31:32