我們為什么不要在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