在react jsx中,为什么使用箭头函数和bind容易出现问题

前端之家收集整理的这篇文章主要介绍了在react jsx中,为什么使用箭头函数和bind容易出现问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在之前的文章中,已经说明如何避免在react jsx中使用箭头函数和bind(https://medium.freecodecamp.o... 但是没有提供一个清晰的demo展示为什么要这样做。

现在来一些例子吧。

在这个例子中,我们通过使用一个箭头函数(=>)来bind用户ID到每个删除按钮中。

  1. ## index.js
  2.  
  3. import React from 'react';
  4. import { render } from 'react-dom';
  5. import User from './User';
  6.  
  7. class App extends React.Component {
  8. constructor(props) {
  9. super(props);
  10. this.state = {
  11. users: [
  12. { id: 1,name: 'Cory' },{ id: 2,name: 'Meg' },{ id: 3,name: 'Bob' }
  13. ]
  14. };
  15. }
  16. deleteUser = id => {
  17. this.setState(prevState => {
  18. return {
  19. users: prevState.users.filter( user => user.id !== id)
  20. }
  21. })
  22. }
  23.  
  24. render() {
  25. return (
  26. <div>
  27. <h1>Users</h1>
  28. <ul>
  29. {
  30. this.state.users.map( user => {
  31. return <User
  32. key={user.id}
  33. name={user.name}
  34. onDeleteClick={() => this.deleteUser(user.id)} />
  35. })
  36. }
  37. </ul>
  38. </div>
  39. );
  40. }
  41. }
  42.  
  43. export default App;
  44.  
  45. render(<App />,document.getElementById('root'));

onDeleteClick={() => this.deleteUser(user.id)}这一行中,我们使用一个箭头函数来传递value到deleteUser 函数中。这就是问题所在了。

  1. ## User.js
  2.  
  3. import React from 'react';
  4.  
  5. // Note how the debugger below gets hit when *any* delete
  6. // button is clicked. Why? Because the parent component
  7. // uses an arrow function,which means this component
  8. //
  9. class User extends React.PureComponent {
  10. render() {
  11. const {name,onDeleteClick } = this.props
  12. console.log(`${name} just rendered`);
  13. return (
  14. <li>
  15. <input
  16. type="button"
  17. value="Delete"
  18. onClick={onDeleteClick}
  19. />
  20. {name}
  21. </li>
  22. );
  23. }
  24. }
  25.  
  26. export default User;

看一看User.js文件。每当我登录的时候控制台都会打印出渲染执行时的console结果。我已经定义UserPureComponent。所以只有当props或者state修改时才会重新渲染User。但是当你点击删除的时候,发现render在所有User实例中触发了。

怎么会这个样子?因为()=>this.deleteUser(user.id)每执行一次就会生成一个新的函数,当然bind也是这样干的,所以在PureComponent的shallowCompare中认为onDeleteClick的值已经被修改,所以触发了重新渲染。看吧,使用箭头函数和bind会造成性能浪费,作为一个节约的程序员应该避免如此。

那我们应该怎样做呢?

请看下面的代码

  1. import React from 'react';
  2. import { render } from 'react-dom';
  3. import User from './User';
  4.  
  5. class App extends React.Component {
  6. constructor(props) {
  7. super(props);
  8. this.state = {
  9. users: [
  10. { id: 1,name: 'Bob'}
  11. ],};
  12. }
  13.  
  14. deleteUser = id => {
  15. this.setState(prevState => {
  16. return {
  17. users: prevState.users.filter(user => user.id !== id)
  18. };
  19. });
  20. };
  21.  
  22. renderUser = user => {
  23. return <User key={user.id} user={user} onClick={this.deleteUser} />;
  24. }
  25.  
  26. render() {
  27. return (
  28. <div>
  29. <h1>Users</h1>
  30. <ul>
  31. {this.state.users.map(this.renderUser)}
  32. </ul>
  33. </div>
  34. );
  35. }
  36. }
  37.  
  38. render(<App />,document.getElementById('root'));

上面的例子就没有箭头函数了。这里面使用了闭包的概念,把user传递下去了。

猜你在找的React相关文章