我们为什么不要在render方法里绑定方法和使用箭头函数?具体原因可以看一下这篇文章。
这样的代码是不是似曾相识:
render() {
const { id } = this.props;
return (
<Picker
...
onChange={this.onDateChange.bind(this)}
toggleOpen={this.onOpen.bind(this)}
onClose={() => {this.onClose(id)}}
...
/>
);
}
这要做不好的原因分为以下几个方面:
- 不论是bind还是箭头函数在render执行时都会返回一个新的方法作为Props,旧的方法会被GC
- 假如我们的组件是继承了PureComponent,那么在组件内部shouldComponentUpdate对比前后Props时,一定是不同的,PureComponent将失去作用
- 如果你使用了eslint,它可能会给你警告,对于要解决一切警告的强迫症患者来说会很不爽,当然你也可以通过eslint的配置允许这样的操作
这些都不会产生程序崩溃之类的大问题,但是如果想让你的程序更规范,可以尝试以下方法:
- 在你的构造函数中绑定方法
constructor(props) {
super(props);
this.onDateChange = this.onDateChange.bind(this);
this.onOpen = this.onOpen.bind(this);
}
<Picker
...
onChange={this.onDateChange}
toggleOpen={this.onOpen}
onClose={() => {this.onClose(id)}}
...
/>
很简单对不对,下面还有更酷的写法
class Demo extends Component {
onDateChange = () => {
// todo
}
onOpen = () => {
// your code
}
onClose = () => {
const { id } = this.props;
// todo close
}
render() {
return (
<Picker
...
onChange={this.onDateChange}
toggleOpen={this.onOpen}
onClose={this.onClose}
...
/>
);
}
}
如果以上方法你知道,但是你还不得不使用bind和箭头函数,那么一定是遇到了传参的问题,可能是下面这样:
class Demo extends Component {
constructor(props) {
super(props);
this.state = {
data: [
{ id: 0, name: '夜刀神·十香' },
{ id: 1, name: '日代千鹤' }
]
};
}
onClick(id) {
const person = this.state.data.find((p) => id === p.id);
// your code
}
onMouseEnter(id) {
// your code
}
render() {
return (
<div>
this.state.data.map((person) => {
const { id, name } = person;
return (
<div
onClick={()=>{this.onClick(id)}}
onMouseEnter={this.onMouseEnter.bind(this, id)}
>
{ name }
</div>
)
})
</div>
);
}
}
这样可以直接把person.id通过箭头函数传入onClick方法,同样也有不使用箭头函数的解决方案
onClick = (e) => {
const id = e.target.dataset.id;
const person = this.state.data.find((p) => id === p.id);
// your code
}
onMouseEnter = (e)=> {
const id = e.target.dataset.id;
// todo
}
render() {
return (
<div>
this.state.data.map((person) => {
const { id, name } = person;
return (
<div
data-id={id}
onClick={this.onClick}
onMouseEnter={this.onMouseEnter}
>
{ name }
</div>
)
})
</div>
);
}
使用data-xx传递参数就可以解决这个问题了。
如有问题欢迎斧正。
参考地址:
https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md
https://medium.com/@machnicki/handle-events-in-react-with-arrow-functions-ede88184bbb