在react中實現事件處理,有多種寫法,那那種寫法相對更優,更利於React的渲染性能呢?前端
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>; } }
class ReactEvent extends Component { handleClick() { console.log('Click'); } render() { return <button onClick={() => this.handleClick()}>Click Me</button>; } }
class ReactEvent extends Component { //此函數會被綁定到ReactEvent類的實例 handleClick = () => { console.log('Click'); } render() { return <button onClick={this.handleClick}>Click Me</button>; } }
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中進行優化。react
bind和箭頭函數相關請參考mdn:
https://developer.mozilla.org...
https://developer.mozilla.org...
//僅做爲示例代碼,不遵循經常使用代碼規範 //子組件 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') );
在開發當中,常常遇到對一個列表作操做,可能包含刪除,修改,查看。這時候綁定事件就須要傳參,一般爲id。babel
//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)}/> )) }
//handleClick中經過e.target.dataset.id獲取 { this.state.list.map(item => ( <Button data-id={item.id} onClick={this.handleClick}/> )) }
這裏不強制推薦使用哪種,對於各個團隊來講,能夠根據項目,選擇本身團隊的事件綁定方式。框架
由於箭頭函數的簡潔性,在公司項目中,咱們團隊一般使用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') );
前端發展巨快,各類新特性,新框架,新UI層出不窮。須要咱們不斷保持學習,深挖技術底層,這樣遇到任何新的技術,纔可以以一法破萬法。性能