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

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

现在来一些例子吧。

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


## index.js 

import React from ‘react‘;
import { render } from ‘react-dom‘;
import User from ‘./User‘;

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      users: [
        { id: 1, name: ‘Cory‘ },
        { id: 2, name: ‘Meg‘ },
        { id: 3, name: ‘Bob‘ }
      ]
    };
  }

  deleteUser = id => {
    this.setState(prevState => {
      return {
        users: prevState.users.filter( user => user.id !== id)
      }
    })
  }

  render() {
    return (
      <div>
        <h1>Users</h1>
        <ul>
        {
          this.state.users.map( user => {
            return <User
              key={user.id}
              name={user.name}
              onDeleteClick={() => this.deleteUser(user.id)} />
          })
        }
        </ul>
      </div>
    );
  }
}

export default App;

render(<App />, document.getElementById(‘root‘));

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


## User.js

import React from ‘react‘;

// Note how the debugger below gets hit when *any* delete
// button is clicked. Why? Because the parent component
// uses an arrow function, which means this component
//
class User extends React.PureComponent {
  render() {
    const {name, onDeleteClick } = this.props
    console.log(`${name} just rendered`);
    return (
      <li>
        <input
          type="button"
          value="Delete"
          onClick={onDeleteClick}
        />
        {name}
      </li>
    );
  }
}

export default User;

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

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

那我们应该怎样做呢?

请看下面的代码


import React from ‘react‘;
import { render } from ‘react-dom‘;
import User from ‘./User‘;

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      users: [
        { id: 1, name: ‘Cory‘ },
        { id: 2, name: ‘Meg‘ },
        { id: 3, name: ‘Bob‘}
      ],
    };
  }

  deleteUser = id => {
    this.setState(prevState => {
      return {
        users: prevState.users.filter(user => user.id !== id)
      };
    });
  };

  renderUser = user => {
    return <User key={user.id} user={user} onClick={this.deleteUser} />;
  }

  render() {
    return (
      <div>
        <h1>Users</h1>
        <ul>
          {this.state.users.map(this.renderUser)}
        </ul>
      </div>
    );
  }
}

render(<App />, document.getElementById(‘root‘));

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

来源:https://segmentfault.com/a/1190000011007769

原文地址:https://www.cnblogs.com/qixidi/p/10160748.html

时间: 2024-10-25 05:20:48

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

js中this,箭头函数和普通函数

四种基本用法 1. 一般方法中,this代指全局对象 window 2. 作为对象方法调用,this代指当前对象 3. 作为构造函数调用,this 指代new 出的对象 function test(){ this.x = 1; } var o = new test(); alert(o.x); //1 4. 调用方法的apply和call方法,可以改变函数的调用对象/作用域 (this)用法: f.apply([thisObj [,argArray] ]); f.call([thisObject

JS中generater和箭头函数

generater跟函数很像: function* fn(x){ yield x; yield x++; return x;} 如上所示,generater用function*定义,可以用yield返回多次,也可以使用return返回; 调用generater有两个方法,一是一直调用generater的next()方法: console.log(fn.next()); console.log(fn.next()); console.log(fn.next()); 直到fn.next()返回tru

react jsx 中使用 switch case 示例

<div> <span>适用平台:</span> <span>{(() => { switch (currentItems.usePlatform) { case 0: return '全平台可用' case 1: return '淘宝' case 2: return '美团' case 3: return '爱奇艺' case 4: return '腾讯' default: return null } } )()}</span></

深入理解ES6箭头函数中的this

简要介绍:箭头函数中的this,指向与一般function定义的函数不同,箭头函数this的定义:箭头函数中的this是在定义函数的时候绑定,而不是在执行函数的时候绑定. (1)一般函数this指向在执行是绑定  当运行obj.say()时候,this指向的是obj这个对象. var x=11; var obj={ x:22, say:function(){ console.log(this.x) } } obj.say(); //console.log输出的是22 (2)所谓的定义时候绑定,就

ES6中箭头函数的作用

我们知道在ES6中,引入了箭头函数,其本质就是等同有ES5中的函数.类似于下面的写法: let test1=() => "abc"; let test2=() => { return "abc"}; let sum=(a,b) => a+b; 比如上面的3个ES6的箭头函数的写完,如果用ES5就像下面的写完一样. 其实其等同于下面的ES5的写法: function test1() { return "abc" } functio

箭头函数中的this

箭头函数中的this 箭头函数根据外层(函数或者全局)作用域来决定this 这样this就像其他面向对象的语言,在哪里定义就指向哪里 function foo() { return (x) => { console.log(this); } } var obj1 = { x: 1 }; var obj2 = { x: 2 }; var bar = foo.call(obj1); bar(); //=> { x: 1 } bar.call(obj2); //=> { x: 1 } foo(

typescript 属性默认值使用箭头函数 this指向问题

今天注意到前端小伙伴用react 定义component class的方法的时候是通过箭头函数的方式,表示好奇. class Test extends React.Component { public fun1 = () => { console.log(this); }; fun2() { console.log(this); } } 如上代码中fun1的定义方式.于是感到好奇,fun1中的this是什么. 如果我们套用箭头函数的概念,我们可能认为,这中间的this是否会指向环境变量globa

有关箭头函数

前言 在react开发中,经常使用bind(this),来将函数绑定上下文,后来使用了箭头函数,就不需要使用bind(this)了.在非箭头函数下, this 指向调用其所在函数的对象,而且是离谁近就是指向谁(此对于常规对象,原型链, getter & setter等都适用):构造函数下,this与被创建的新对象绑定:DOM事件,this指向触发事件的元素:内联事件分两种情况,bind绑定, call & apply 方法等, 容以下一步一步讨论.箭头函数也会穿插其中进行讨论.关于this

箭头函数

在ES6以前我们用 function 来定义函数,还记得楼主刚学js那会儿老是把function写错 (╯‵□′)╯︵┻━┻,但是自从ES6中出现了箭头函数以后,妈妈再也不担心我写成 fnuction了,那么我们下面开始正式学习! 基本语法: ES6允许使用"箭头"(=>)定义函数. let func = (num) => num; 上面的箭头函数等同于: let func = function (num) { return num; } 小伙伴们发现了什么?没错, ES6