如何避免render方法中的绑定或内联箭头功能

JavaScript React.js

小胖Gil

2020-05-28

我们应该避免在render内部绑定方法,因为在重新渲染过程中它将创建新方法而不是使用旧方法,这会影响性能。

所以对于这样的场景:

<input onChange = { this._handleChange.bind(this) } ...../>

我们可以_handleChange在构造函数中绑定方法:

this._handleChange = this._handleChange.bind(this);

或者我们可以使用属性初始化器语法

_handleChange = () => {....}

现在让我们考虑一下要传递一些额外参数的情况,比如说在一个简单的todo应用中,项目的onclick我需要从数组中删除该项目,为此我需要在每个项目中传递项目索引或todo名称onClick方法:

todos.map(el => <div key={el} onClick={this._deleteTodo.bind(this, el)}> {el} </div>)

现在,仅假定待办事项名称是唯一的。

根据DOC

这种语法的问题在于,每次渲染组件时都会创建一个不同的回调。

题:

如何避免这种在render方法中进行绑定的方式,或者有什么替代方法?

请提供任何参考或示例,谢谢。

第4192篇《如何避免render方法中的绑定或内联箭头功能》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

2个回答
西门 2020.05.28

文档鼓励使用数据属性并从以下位置访问它们evt.target.dataset

_deleteTodo = (evt) => {
  const elementToDelete = evt.target.dataset.el;
  this.setState(prevState => ({
    todos: prevState.todos.filter(el => el !== elementToDelete)
  }))
}

// and from render:

todos.map(
  el => <div key={el} data-el={el} onClick={this._deleteTodo}> {el} </div>
)

Also note that this makes sense only when you have performance issues:

Is it OK to use arrow functions in render methods?

Generally speaking, yes, it is OK, and it is often the easiest way to pass parameters to callback functions.

If you do have performance issues, by all means, optimize!

飞云 2020.05.28

这个答案https://stackoverflow.com/a/45053753/2808062肯定是详尽无遗的,但我想说最好shouldComponentUpdate在子组件中实现一个适当的方法来解决此问题

即使道具完全相同,以下代码仍将重新渲染子级,除非它们自己阻止子级shouldComponentUpdate(它们可能从继承PureComponent):

handleChildClick = itemId => {}

render() {
    return this.props.array.map(itemData => <Child onClick={this.handleChildClick} data={itemData})
}

证明:https : //jsfiddle.net/69z2wepo/92281/

因此,为了避免重新渲染,shouldComponentUpdate无论如何都必须实现子组件现在,唯一合理的实现是完全忽略onClick,无论它是否已更改:

shouldComponentUpdate(nextProps) {
    return this.props.array !== nextProps.array;
}

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android