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. 在元素中使用箭头函数,这样子可以传参,但是会发现这样子只不过是把相同的函数放到不同的内存里面
阅读 5.9k
4 个回答

嗨,如果不希望用匿名函数的话,可以将 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...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏