在JSX循环中将数据传输到函数:作用域函数与数据属性

时间:2019-02-01 10:26:42

标签: reactjs

我与同事进行了很长时间的讨论,以便在向函数发送数据(例如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>

我尝试对此主题进行了一些研究,但没有发现任何深入的比较。

2 个答案:

答案 0 :(得分:2)

基本上,整个论点是内联函数是不好的cos,它们在每次渲染时都会重新创建,并导致不必要的子级重新渲染。尽管从技术上讲是正确的,但我从未遇到过导致性能问题的情况。基本上,只有一个元素可以同时渲染数百个孩子(并且如果频繁地重新渲染孩子,则会加剧它)。

通常,即使没有没有性能的内联函数,也不应该同时渲染成百上千的东西。最好做一些诸如分页数据之类的事情。但是,如果您这样做了,那么在性能方面,类似于第三种方法(在父方法中创建一个绑定函数并将其传递给子方法)会更好。因为在那种情况下,即使父母重新渲染,所有孩子的onClick所引用的功能也没有改变,因此他们也不会重新渲染(假设其他道具也没有变化)。

请注意,请勿使用index作为键,否则在添加/删除项目时会导致错误的行为。 React将无法正确跟踪列表的更新。如果要编辑列表,则每个项目都需要一个唯一的标识符作为其键。

简而言之,您可以 使用内联函数,除非您确定将要渲染很多子代和/或子代会非常频繁地渲染。如果您使用Google“反应内联函数”或类似的方法,则可以找到很多有关此事的文章。

答案 1 :(得分:-1)

如果您愿意将参数index传递给deleteTodo,则需要像这样()=>this.deleteTodo(index)来调用它 您应该使用箭头功能()=>,否则它将与render()功能同时运行 所以第一个解决方案是正确的,其他解决方案是错误的