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語法(https://babeljs.io/docs/en/ba...)
class ReactEvent extends Component { //此函數會被綁定到ReactEvent類的實例 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中進行優化。
//僅作為示例代碼,不遵循常用代碼規范 //子組件 class Button extends React.PureComponent { render() { console.log('================') return ( <button onClick={this.props.handleClick}>hahaha</button> ) } } //父組件 class ButtonList extends React.Component { constructor(props) { super(props); this.state = { index: -1, list: [1, 2, 3, 4] }; this.handleClick = this.handleClick.bind(this); } handleClick() { console.log('Click'); } onStateChange = () => { this.setState({ index: 1 }); } render() { return ( <div> <button onClick={this.onStateChange}>stateChange</button> { this.state.list.map(item => <Button handleClick={this.handleClick}/>) } </div> ) } } ReactDOM.render( <ButtonList />, document.getElementById('root') );
1
事件處理中傳參
在開發當中,經常遇到對一個列表做操作,可能包含刪除,修改,查看。這時候綁定事件就需要傳參,通常為id。
直接傳遞參數
//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)}/> )) }
使用data屬性
//handleClick中通過e.target.dataset.id獲取 { this.state.list.map(item => ( <Button data-id={item.id} onClick={this.handleClick}/> )) }
資源搜索網站大全 https://www.renrenfan.com.cn 廣州VI設計公司https://www.houdianzi.com
總結
這里不強制推薦使用哪一種,對於各個團隊來說,可以根據項目,選擇自己團隊的事件綁定方式。
因為箭頭函數的簡潔性,在公司項目中,我們團隊通常使用class fields 定義箭頭函數來綁定事件。當需要傳參的時,單個參數傳遞使用data屬性傳參。多個參數傳遞時,采用拆分子組件的方式回調傳參。
//子組件 class Button extends React.PureComponent { handleClick = () => { this.props.handleClick(this.props.item); } render() { return ( <button onClick={this.handleClick}>hahaha</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> ) } } ReactDOM.render( <ButtonList />, document.getElementById('root') );
