在 react 中实现事件处理,有如下几种
第一种:在 constructor 函数中用 bind 方法
class ReactEvent extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log('Click');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}
第二种:使用箭头函数(render 中使用箭头函数)
class ReactEvent extends Component {
handleClick() {
console.log('Click');
}
render() {
return <button onClick={() => this.handleClick()}>Click Me</button>;
}
}
第三种:使用 class fields 语法
class ReactEvent extends Component {
handleClick = () => {
console.log('Click');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}
第四种:在 render 中使用 bind 方法
class ReactEvent extends Component {
handleClick() {
console.log('Click');
}
render() {
return <button onClick={this.handleClick.bind(this)}>Click Me</button>;
}
}
几种方式的比较
影响 | constructor函数中bind | 使用class fields语法 | render中使用箭头函数 | 在render中使用bind |
---|---|---|---|---|
render时生成新函数 | 否 | 否 | 是 | 是 |
性能 | 无影响 | 无影响 | 有影响 | 有影响 |
可直接携带参数 | 否 | 否 | 是 | 是 |
在render中直接bind或者箭头函数都会影响性能,原因在于,在 render 中的 bind 和箭头函数在每次 render 时都会创建新的函数,导致子组件的 props 发生改变,这在 PureComponent 中会影响性能,除非自己在 shouldComponentUpdate 中进行优化。
参数传递
直接传递参数, render 中使用箭头函数
this.state.list.map(item => (
<Button onClick={() => this.handleClick(item.id)}/>
))
直接传递参数, render 中使用 bind
this.state.list.map(item => (
<Button onClick={this.handleClick.bind(this, item.id)}/>
))
推荐的方式
//子组件
class Button extends React.PureComponent {
handleClick = () => {
this.props.handleClick(this.props.item);
}
render() {
return (
<button onClick={this.handleClick}>hello world</button>
)
}
}
//父组件
class ButtonList extends React.Component {
constructor(props) {
super(props);
this.state = {
list: [1, 2, 3, 4]
};
}
handleClick = (item) => {
console.log('Click', item);
}
render() {
const { list=[] } = this.state;
return (
<div>
{
list.map(item => <Button handleClick={this.handleClick} item={item}/>)
}
</div>
)
}
}