【问题标题】:React passing parameter via onclick event using ES6 syntax使用 ES6 语法通过 onclick 事件响应传递参数
【发布时间】:2016-03-24 21:20:47
【问题描述】:

如何使用 ES6 语法向 onClick 事件传递额外的参数?

例如:

handleRemove = (e) => {

}

render() {
     <button onClick={this.handleRemove}></button>
}

我想像这样将 id 传递给 handleRemove 函数:

<button onClick={this.handleRemove(id)}></button>

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    像这样使用箭头函数:

    <button onClick={()=>{this.handleRemove(id)}}></button>
    

    【讨论】:

    • 这会在每个渲染上创建一个新函数,这对性能来说不是很好。 ESLint 默认标记它:github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/…
    • @craigpatik 因此,如果您要创建一个命名函数作为属性初始值设定项或通过构造函数中的 .bind 并使用它来代替如上所示的匿名箭头函数,它将阻止创建新函数在每次渲染时.. 你仍然可以在其中 curry 你的第二个 this.handleRemove(id) 函数吗?
    • Linting 错误:JSX functions should not use arrow functions react/jsx-no-bind
    【解决方案2】:

    请记住,在onClick={ ... } 中,... 是一个 JavaScript 表达式。所以

    ... onClick={this.handleRemove(id)}
    

    相同
    var val = this.handleRemove(id);
    ... onClick={val}
    

    换句话说,您立即调用this.handleRemove(id),然后将该值传递给onClick,这不是您想要的。

    相反,您想创建一个 new 函数,其中一个参数已经预填充;本质上,您需要以下内容:

    var newFn = function() {
      var args = Array.prototype.slice.call(arguments);
    
      // args[0] contains the event object
      this.handleRemove.apply(this, [id].concat(args));
    }
    ... onClick={newFn}
    

    在 ES5 JavaScript 中有一种表达方式:Function.prototype.bind

    ... onClick={this.handleRemove.bind(this, id)}
    

    如果你使用React.createClass,React 会在实例方法上自动为你绑定this,除非你将其更改为this.handleRemove.bind(null, id),否则它可能会报错。

    你也可以简单的内联定义函数;如果您的环境或转译器支持arrow functions,这会缩短:

    ... onClick={() => this.handleRemove(id)}
    

    如果您需要访问该事件,您可以直接传递它:

    ... onClick={(evt) => this.handleRemove(id, evt)}
    

    【讨论】:

    • 如何以这种方式(es6)在 onClick 函数中使用 event.preventDefault() 和 this.handleRemove(id,etv)。
    • 值得一提的是,箭头函数每次都会导致重新渲染,因为每次渲染都会创建新函数
    • 感谢“传递事件”部分,今天它救了我
    • 绝对应该有人写下这个“陷阱”(也许是一篇博文)?我会写这篇文章,但我正在学习 ReactJS(和高级 Javascript),但这个技巧非常重要。所以,作为新手,我做了this._deleteText(result.text),当我的表格加载时,每个带有删除按钮的表格行都会触发删除调用......哎呀!
    • 需要注意的是,在渲染方法中添加箭头函数会在每次新渲染时创建一个新函数。不过,它会起作用。最好在构造函数中创建新的绑定函数,并将新函数添加到render方法中。
    【解决方案3】:
    onClick={this.handleRemove.bind(this, id)}
    

    使用箭头函数

    onClick={()=>{this.handleRemove(id)}}
    

    【讨论】:

    • 不知道为什么有人不赞成这个。它对我有用。这样做是否被认为是不好的形式?
    • No Cari...完美,您可以使用它。
    • 这与接受的答案基本相同。而且它效率不高,因为它在每次渲染上都创建了一个新函数。您应该在构造函数中绑定函数,而不是在渲染方法中。所以,可行,但性能成本可能很高。
    • Linting 错误:JSX props should not use .bind() react/jsx-no-bind
    【解决方案4】:

    到目前为止没有人提到的是让 handleRemove 返回一个函数。

    你可以这样做:

    handleRemove = id => event => {
      // Do stuff with id and event
    }
    
    // render...
      return <button onClick={this.handleRemove(id)} />
    

    但是,所有这些解决方案都有在每次渲染时创建新函数的缺点。最好为 Button 创建一个新组件,分别通过 idhandleRemove

    【讨论】:

    • 我不知道为什么这被赞成,3 次!这不会将 this.handleRemove 函数绑定到 onClick 事件,它会在组件呈现时立即执行它,然后将它返回的任何内容绑定到 onClick 事件。
    • @GiovanniLobitos 最后你得到一个可以访问idevent 并执行handleRemove() 职责的函数。不确定您遇到的问题是什么?您在实施时遇到任何问题吗? “不管它返回什么”是前面提到的可以访问idevent 的函数。
    • 我明白了。就在那里糊涂了。感谢您的澄清。
    【解决方案5】:

    使用按钮元素的value attribute传递id,为

    <button onClick={this.handleRemove} value={id}>Remove</button>
    

    然后在handleRemove中,从事件中读取值:

    handleRemove(event) {
    ...
     remove(event.target.value);
    ...
    }
    

    这样可以避免每次重新渲染此组件时都创建一个新函数(与使用箭头函数相比)。

    【讨论】:

    • 简单又好用。当按钮中有一个图标/字形时出现问题,但值未定义。只需使用event.currentTarget.value 而不是event.target.value 就可以了。
    • 很高兴它对您有所帮助。在我的示例中,我假设
    • 我发现在这里使用一个简单的函数来处理事件更简洁。绑定或创建返回另一个函数的函数的方法都会产生大量垃圾,因为将创建一个新函数并丢弃旧函数以在每次渲染时进行垃圾收集。
    • 我收到Uncaught TypeError: Cannot read property 'handleRemove' of undefined。这甚至是在我的constructor(props) 顶部执行this.handleRemove = this.handleRemove.bind(this); 之后。
    【解决方案6】:

    TL;DR:

    不要在渲染方法中绑定函数(也不要使用箭头函数)。请参阅官方建议。

    https://reactjs.org/docs/faq-functions.html


    所以,有一个公认的答案和几个相同的答案。还有一些 cmets 阻止人们在渲染方法中使用bind,并且出于同样的原因也避免在那里使用箭头函数(这些函数将在每次渲染时一次又一次地创建)。但是没有例子,所以我写一个。

    基本上,你必须在构造函数中绑定你的函数。

    class Actions extends Component {
    
        static propTypes = {
            entity_id: PropTypes.number,
            contact_id: PropTypes.number,
            onReplace: PropTypes.func.isRequired,
            onTransfer: PropTypes.func.isRequired
        }
    
        constructor() {
            super();
            this.onReplace = this.onReplace.bind(this);
            this.onTransfer = this.onTransfer.bind(this);
        }
    
        onReplace() {
            this.props.onReplace(this.props.entity_id, this.props.contact_id);
        }
    
        onTransfer() {
            this.props.onTransfer(this.props.entity_id, this.props.contact_id);
        }
    
        render() {
            return (
                <div className="actions">
                    <button className="btn btn-circle btn-icon-only btn-default"
                        onClick={this.onReplace}
                        title="Replace">
                            <i className="fa fa-refresh"></i>
                    </button>
                    <button className="btn btn-circle btn-icon-only btn-default"
                        onClick={this.onTransfer}
                        title="Transfer">
                        <i className="fa fa-share"></i>
                    </button>                                 
                </div>
            )
        }
    }
    
    export default Actions
    

    关键行是:

    构造函数

    this.onReplace = this.onReplace.bind(this);

    方法

    onReplace() {
        this.props.onReplace(this.props.entity_id, this.props.contact_id);
    }
    

    渲染

    onClick={this.onReplace}
    

    【讨论】:

    • 'PropTypes' is not defined。你错过了什么。
    • 当然是@vapcguy。你必须导入它:import PropTypes from 'prop-types'
    • 很好的答案 - 很想知道它如何与 this.setState 而不是 props 一起工作。我在结束循环时遗漏了一些东西。
    • 如果这些函数被定义为常量变量呢?
    • @akkonrad,它会是一样的。事实上,每次执行 render 方法时,都会在堆上创建一个新函数。但是,请注意,现在我们有了 react 钩子,并且在渲染时声明函数是常见的做法,但据我所知,只有使用钩子,因为在这种情况下,react 团队会处理性能。
    【解决方案7】:

    我正在使用 React-Bootstrap。下拉菜单的 onSelect 触发器不允许我传递数据。只是事件。所以请记住,您可以将任何值设置为属性并使用 javascript 从函数中获取它们。获取您在该事件目标中设置的那些属性。

        let currentTarget = event.target;
        let currentId = currentTarget.getAttribute('data-id');
        let currentValue = currentTarget.getAttribute('data-value');
    

    【讨论】:

      【解决方案8】:

      我使用以下代码:

      <Button onClick={this.onSubmit} id={item.key} value={shop.ethereum}>
          Approve
      </Button>
      

      然后在方法里面:

      onSubmit = async event => {
          event.preventDefault();
          event.persist();
          console.log("Param passed => Eth addrs: ", event.target.value)
          console.log("Param passed => id: ", event.target.id)
          ...
      }
      

      结果:

      在事件中传递的参数 => Eth 地址:0x4D86c35fdC080Ce449E89C6BC058E6cc4a4D49A6

      在事件中传递的参数 => id: Mlz4OTBSwcgPLBzVZ7BQbwVjGip1

      【讨论】:

      • 这是一个重复的答案。请参阅 Praym 的解决方案。
      【解决方案9】:

      在函数组件中,这很有效 - 自 2020 年以来的新 React 用户 :)

      handleRemove = (e, id) => {
          //removeById(id);
      }
      
      return(<button onClick={(e)=> handleRemove(e, id)}></button> )
      

      【讨论】:

        猜你喜欢
        • 2017-07-24
        • 1970-01-01
        • 2014-05-10
        • 1970-01-01
        • 1970-01-01
        • 2012-09-04
        • 2011-03-30
        • 2019-12-27
        • 1970-01-01
        相关资源
        最近更新 更多