我与同事进行了很长时间的讨论,以便在向函数发送数据(例如ID或键)时在两个(或三个)概念之间做出决定。我的问题更多是关于(记忆)性能以及语法糖。
考虑这个小应用程序:
export default class Untitled extends Component {
state = { todos: ["first todo", "second todo", "third todo"] }
deleteTodo(???) {
// some array slice to remove a todo
}
render() {
return (
<ul>
{this.state.todos.map((todo, index) =>
<li key={index}>{todo} <a onClick={ ??? }>delete</a>
</li>
}
</ul>
)
}
}
如何以最有效的方式从用户单击的待办事项中获取deleteTodo()
方法的ID?我可以想到三种方式:
第一:
<li key={index}>{todo} <a onClick={ () => { this.deleteTodo(index) } }>delete</a></li>
第二:
deleteTodo(id) {
return ()=>{
// some array slice to remove a todo
}
}
<li key={index}>{todo} <a onClick={ this.deleteTodo(index) }>delete</a></li>
第三:
deleteTodo(event) {
const { id } = event.currentTarget.dataset
// some array slice to remove a todo
}
<li key={index}>{todo} <a data-id={index} onClick={ this.deleteTodo }>delete</a></li>
这三个选项中最好的是什么,为什么?我一直使用方法一(就性能而言,应该基本上等于方法二),但是在讨论之后,我开始怀疑自己方法三是否性能更好,因为它不会为每个渲染调用创建太多的函数实例? / p>
我尝试对此主题进行了一些研究,但没有发现任何深入的比较。
答案 0 :(得分:2)
基本上,整个论点是内联函数是不好的cos,它们在每次渲染时都会重新创建,并导致不必要的子级重新渲染。尽管从技术上讲是正确的,但我从未遇到过导致性能问题的情况。基本上,只有一个元素可以同时渲染数百个孩子(并且如果频繁地重新渲染孩子,则会加剧它)。
通常,即使没有没有性能的内联函数,也不应该同时渲染成百上千的东西。最好做一些诸如分页数据之类的事情。但是,如果您这样做了,那么在性能方面,类似于第三种方法(在父方法中创建一个绑定函数并将其传递给子方法)会更好。因为在那种情况下,即使父母重新渲染,所有孩子的onClick
所引用的功能也没有改变,因此他们也不会重新渲染(假设其他道具也没有变化)。
请注意,请勿使用index
作为键,否则在添加/删除项目时会导致错误的行为。 React将无法正确跟踪列表的更新。如果要编辑列表,则每个项目都需要一个唯一的标识符作为其键。
简而言之,您可以 使用内联函数,除非您确定将要渲染很多子代和/或子代会非常频繁地渲染。如果您使用Google“反应内联函数”或类似的方法,则可以找到很多有关此事的文章。
答案 1 :(得分:-1)
如果您愿意将参数index
传递给deleteTodo
,则需要像这样()=>this.deleteTodo(index)
来调用它
您应该使用箭头功能()=>
,否则它将与render()
功能同时运行
所以第一个解决方案是正确的,其他解决方案是错误的