React 构造函数绑定事件如何传参

class albumList extends PureComponent {
    constructor(props) {
        super(props)
        this.play = this.play.bind(this)
    }
    play(song) {
        console.log(song)
    }
    render() {
        return(
            <div className="album-list">
                {
                    this.props.data.map((item,index)=>{
                        return (
                            <div className="album-list-item" key={index}>
                                    <img onClick={this.play } alt="" src="./img/album-list-play.png" />
                            </div>
                        )
                    })
                }
            </div>
        );
    }
}

上面的代码中,事件 play 在构造函数中使用bind的方式绑定,但是发现好像穿不了参数,在构造函数中绑定事件这样的方式是react中比较推荐的优化方案,而又想传参的话,该怎么写呢?

react绑定事件的方式:

  1. 在元素中直接bind绑定方法,但是每次render的时候都会触发到函数
  2. 在元素中使用箭头函数,这样子可以传参,但是会发现这样子只不过是把相同的函数放到不同的内存里面
阅读 2.1k
评论
    4 个回答
    • 9k

    嗨,如果不希望用匿名函数的话,可以将 img 抽象一层组件,供参考:

    class AlbumItem extends React.PureComponent {
      onClick = () => this.props.onClick && this.props.onClick(this.props.song)
      render () {
        const { song, onClick, ...restProps } = this.props
        return <img {...restProps} onClick={this.onClick} />
      }
    }

      你不知道bind函数可以有多个参数吗,另外在构造函数里传递参数似乎没有什么意义

        constructor里的bind只是把该方法运行时的this绑定到组件实例上,调用方法不变。

        所以参数是在调用的时候传的,前面的bind相当于每次都这样调用:

        this.play.call(this, arguments)

          onClick的时候是会有event传给你的

          
          class albumList extends PureComponent {
              constructor(props) {
                  super(props)
                  this.play = this.play.bind(this)
              }
              play(e) {
                  console.log(e.target.getAttribute('src'));
              }
              render() {
                  return <img onClick={this.play } src="./img/album-list-play.png" />;
              }
          }
          

          一些id,name之类的参数,也可以这样传递

          
          class albumList extends PureComponent {
              constructor(props) {
                  super(props)
                  this.play = this.play.bind(this)
              }
              play(e) {
                  // data-前缀,只是一种规范,没有实际意义
                  console.log(e.target.getAttribute('data-id'));
              }
              render() {
                  return <img
                   onClick={this.play }
                   src="./img/album-list-play.png"
                   data-id={12}
                 />;
              }
          }
          

          还有你的bind太麻烦了,尤其是比较复杂的组件,要一直.bind(this)。给你推荐一个装饰器

          import {autobind} from 'core-decorators';
          
          class albumList extends PureComponent {
              @autobind
              play(e) {
                // play 已经自动bind了
              }
              
              render() {
                return '一个插件';
              }
              
          }
          

          下载地址:
          https://www.npmjs.com/package...

            撰写回答

            登录后参与交流、获取后续更新提醒

            相似问题
            推荐文章