【问题标题】:ReactJS distinguishing clicks from multiple components.ReactJS 将点击与多个组件区分开来。
【发布时间】:2014-12-02 23:04:00
【问题描述】:

我有一个带有两个按钮的网络界面:

<Panel header="Green Square">
  <ButtonToolbar>
    <Button bsStyle="info" onClick={this.handleGreenSquareOn}><Glyphicon glyph="ok-circle"/> On</Button>
    <Button bsStyle="info" onClick={this.handleGreenSquareOff}><Glyphicon glyph="remove-circle"/> Off</Button>
  </ButtonToolbar>
</Panel>

还有一些处理代码:

handleGreenSquareOn: function() { return this.handleGreenSquare(true); },
handleGreenSquareOff: function() { return this.handleGreenSquare(false); },
handleGreenSuqare: function(value) {
  // do stuff
},

消除handleGreenSquareOnhandleGreenSquareOff 函数的最佳方法是什么?

有没有办法在 JSX 代码中为 onClick 回调设置参数?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    事件回调将提供 data-reactid 作为第二个变量

    所以如果你像这样改变你的功能:

    handleGreenSuqare: function(value, reactId) {
      // do stuff with reactId
    },
    

    你可以解析reactId,它是由点连接的组件键。

    如果你给你的按钮一个关键属性,像这样:

    <Panel header="Green Square">
      <ButtonToolbar>
        <Button key="on" bsStyle="info" onClick={this.handleGreenSquareOn}><Glyphicon glyph="ok-circle"/> On</Button>
        <Button key="off" bsStyle="info" onClick={this.handleGreenSquareOff}><Glyphicon glyph="remove-circle"/> Off</Button>
      </ButtonToolbar>
    </Panel>
    

    对于关闭按钮,您的 reactId 变量看起来有点像这样:

    .0.0.1.0.1.$off
    

    内联函数可能更具表现力,具体取决于您要执行的操作。

    <Panel header="Green Square">
      <ButtonToolbar>
        <Button bsStyle="info" onClick={function() {return this.handleGreenSquare(true);}}><Glyphicon glyph="ok-circle"/> On</Button>
        <Button bsStyle="info" onClick={function() {return this.handleGreenSquare(false);}}><Glyphicon glyph="remove-circle"/> Off</Button>
      </ButtonToolbar>
    </Panel>
    

    如果你使用 jsx 编译器的 es6 Harmony 特性,这看起来不错且富有表现力:

    <Panel header="Green Square">
      <ButtonToolbar>
        <Button key="on" bsStyle="info" onClick={() => this.handleGreenSquare(true)}><Glyphicon glyph="ok-circle"/> On</Button>
        <Button key="off" bsStyle="info" onClick={() => this.handleGreenSquare(false)}><Glyphicon glyph="remove-circle"/> Off</Button>
      </ButtonToolbar>
    </Panel>
    

    【讨论】:

    • 很酷,但我实际上并不推荐这个,而且 reactid 可能很快就会消失。
    • 我完全同意,使用带有 .bind 或内联的函数要好得多,应该更清楚地表明这可能不是一个聪明的主意。
    【解决方案2】:

    您可以像这样将参数传递给handleGreenSquareonClick={this.handleGreenSquare.bind(this, true)}

    这是一个可以玩的 jsfiddle: http://jsfiddle.net/nilgundag/wsdr48ro/

    /** @jsx React.DOM */
    
    var Hello = React.createClass({
            handleGreenSquare: function(value) {
              console.log(value);
            },
        render: function() {
            return <ReactBootstrap.Navbar brand="Whoops">
                   <ReactBootstrap.Panel header="Green Square">
                         <ReactBootstrap.ButtonToolbar>
                <ReactBootstrap.Button bsStyle="info" onClick={this.handleGreenSquare.bind(this, true)}><ReactBootstrap.Glyphicon glyph="ok-circle"/> On</ReactBootstrap.Button>
                <ReactBootstrap.Button bsStyle="info" onClick={this.handleGreenSquare.bind(this, false)}><ReactBootstrap.Glyphicon glyph="remove-circle"/> Off</ReactBootstrap.Button>
              </ReactBootstrap.ButtonToolbar>
    
                </ReactBootstrap.Panel>
            </ReactBootstrap.Navbar>;
        }
    });
    
    React.renderComponent(<Hello />, document.body);
    

    【讨论】:

    • 我忘记了 bind 不仅仅可以用于设置this。很好的答案,谢谢。
    • 这很好用,但我最近开始使用处理程序生成器而不是绑定,因为绑定,IMO,在onClick={} 中看起来有点难看。例如,您创建了一个名为handleClickGenerator 的函数,它接受foo 的参数并返回一个处理函数,如return function(e) {...}。然后在您的 JSX 中,只需执行 `onClick={this.handleClickGenerator('bar')} 即可访问处理函数中的 var 并执行逻辑或其他操作。
    • @Mike 会在每个点击事件上创建一个新的处理函数,这似乎效率低下。为什么不重用一个处理程序并在处理程序函数中执行逻辑呢?
    • @David 在我看来,我们谈论的是极其微不足道的低效率,以显着提高代码的可读性。另外,.bind() 也不是免费的。
    • @Mike 我同意.bind() 几乎是一样的。我更喜欢在所有组件中保持 DOM 事件处理程序的一致性,因为这样我就不必环顾四周来了解它是如何工作的。正如您所说,这本质上是一个设计决策。
    【解决方案3】:

    修改处理程序的参数也会删除事件对象(除非您手动传递它)。为了保持一致性,我会保持处理程序的完整性,但这是一种设计选择。

    另一个选项是添加一个数据属性并在处理程序中检查它:

    handleGreenSquare: function(e) {
      var value = e.currentTarget.getAttribute('data-value') == 'on';
    }
    

    [...]

    <Button data-value="on" key="on" bsStyle="info" onClick={this.handleGreenSquare}><Glyphicon glyph="ok-circle"/> On</Button>
    <Button data-value="off" key="off" bsStyle="info" onClick={this.handleGreenSquare}><Glyphicon glyph="remove-circle"/> Off</Button>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多