如何在React.js中为同一事件添加多个事件处理程序

14

大家好:

我想知道是否有可能将多个事件处理程序绑定到同一个事件上?

比如:

var LikeToggleButton = React.createClass({
    render: function(){
        (function toggle(){
            this.setState({liked:!like});
        }).bind(this);
        return (
            <div onClick={toggle}>TOGGLE LIKE</div>  
        );
    }
});

到目前为止,一切都很正常,但我想为该按钮添加另一个功能,这取决于其他选项:

例如,我有另一个开关组件(可以是复选框或单选按钮等)称为"计数切换",当启用时,LikeToggleButton的按钮将添加另一个onClick处理程序,用于开始计算按钮点击次数。 我知道它可以预先设计成切换函数,但我想知道是否有一种方法将此部分附加到onClick处理程序?

谢谢


4个回答

8
如果您希望在触发 onClick 时执行多个回调,可以将它们从外部传递,这样您就可以在 props 对象中访问它们。然后执行它们所有(注意:代码未经测试):
var LikeToggleButton = React.createClass({

    toggle: function() {
        this.setState({liked:!like});
    },

    handleClick: function(e) {
        e.preventDefault();
        this.toggle();
        for (var i=0, l<this.props.callbacks.length; i<l; i++) {
           this.props.callbacks[i].call();
        }
    },

    render: function() {            
        return (
            <div onClick={this.handleClick}>TOGGLE LIKE</div>  
        );
    }
});

但是,如果您想要让组件彼此连接,不应该在处理程序内调用方法来实现。相反,您应该使用一种架构模式,其中Flux是显而易见的选择(但还有很多其他选择)。

请查看Flux,这里还有更多选择


谢谢,这是个好主意,有一件事需要澄清:在 this.props.callbacks 中,我怎么知道哪个函数是新添加的 CLICK 事件? - Kuan
每次组件被渲染时,它都会接收一个新的 callbacks 数组,因此这并不重要。 - gontrollez
谢谢,我对React还不太熟悉。那个回调函数数组应该放在哪里? - Kuan
在创建组件时,您需要传递参数: <LikeToggleButton callbacks={callbacksArray} />。我建议您仔细阅读 React 文档。 - gontrollez
谢谢,我的意思是如果我在回调函数中添加新的处理程序函数(它可以是单击或其他事件的处理程序),我如何知道它是用于单击事件的?所以我想问是否应该有多个回调数组来处理专用事件? - Kuan

2

如果要实现一种可扩展的方式,而不需要组件了解使用它的组件 - 在更改 onClick 事件之前保存它。 这是从实际工作代码中提取的亮点:

button.jsx

class Button extends React.Component {

  constructor(props) {
    super(props);
    this.state= { callback: false};
  }

  click(){
    //do stuff here
    if(this.state.callback) { this.state.callback.call(); }
  }

  render () {
    this.state.callback = this.props.onClick; // save the onClick of previous handler

    return (
      <button { ...this.props } type={ this.props.type || "button" } onClick={ this.click.bind(this) } className = this.props.className } >
        { this.props.children }
      </button>
    );
  }
}
export default Button;

然后在另一个组件中,您可以使用该按钮,并且它可以有自己的onClick处理程序:

class ItemButtons extends React.Component {
  itemClick () {
    //do something here;
  }

render () {
    const buttons = [
      (
          <Button onClick={ this.itemClick.bind(this) } className="item-button">
            <span>Item-Button</span>
          </Button>
      )
    ];

    return (<section>{ buttons }</section>);
}

export default ItemButtons;

-2

为了在一个事件上分组多个操作

onMouseDown={(e) => { e.stopPropagation(); alert('hello'); }}

这会导致无用的DOM更新,因为onMouseDown将在每次渲染时成为一个新函数。 - grabantot

-2

也许您可以像这里描述的那样,在同一个目标上设置多个点击事件处理程序:https://gist.github.com/xgqfrms-GitHub/a36b56ac3c0b4a7fe948f2defccf95ea#gistcomment-2136607

代码(从上面的链接复制):

<div style={{ display: 'flex' }}>
    <div style={{
            width: '270px',
            background: '#f0f0f0',
            borderRight: "30px solid red",
            minHeight: ' 500px',
            maxHeight: '700px',
            overflowX: 'hidden',
            overflowY: 'scroll',
        }}
        onClick={this.state.ClickHandler}
        onClick={this.stateHandleClick}
        className="sidebar-btn"
        >
        <button onClick={this.props.ClickHandler}>props</button>
        <button onClick={(e) => this.props.ClickHandler}>props</button>
        <button onClick={this.props.ClickHandler}>props</button>
        <button onClick={this.state.ClickHandler}>state</button>
 //...
</div>

这样不行。第二个 onClick 属性会覆盖第一个。 - Krisztián Balla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接