在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层出不穷。须要咱们不断保持学习,深挖技术底层,这样遇到任何新的技术,才可以以一法破万法。性能