在之前的文章中,已经说明如何避免在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

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

  1. 在react jsx中使用if判断

    在react jsx中如果使用if判断,需要这样做 var loginButton; if (loggedIn) { loginButton = <LogoutButton />; } e ...

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

    四种基本用法 1. 一般方法中,this代指全局对象 window 2. 作为对象方法调用,this代指当前对象 3. 作为构造函数调用,this 指代new 出的对象 function test() ...

  3. JS中generater和箭头函数

    generater跟函数很像: function* fn(x){ yield x; yield x++; return x;} 如上所示,generater用function*定义,可以用yield返 ...

  4. JS 函数(arguments、箭头函数、bind)

    参数 函数内部可用的 arguments 对象来访问函数的实参 注意 在函数递归调用的时候(在某一刻同一个函数运行了多次,也就是有多套实参),那么 arguments 属性的值是最近一次该函数调用时传 ...

  5. es6中的双箭头函数

    原代码: const fetchPosts = subreddit => dispatch => { dispatch(requestPosts(subreddit)); return c ...

  6. react jsx 中使用 switch case 示例

    <div> <span>适用平台:</span> <span>{(() => { switch (currentItems.usePlatform ...

  7. 普通函数跟箭头函数中this的指向问题

    箭头函数和普通函数的区别如下. 普通函数:根据调用我的人(谁调用我,我的this就指向谁) 箭头函数:根据所在的环境(我再哪个环境中,this就指向谁) 一针见血式总结: 普通函数中的this: 1. ...

  8. => js 中箭头函数使用总结

    箭头函数感性认识 箭头函数 是在es6 中添加的一种规范 x => x * x 相当于 function(x){return x*x} 箭头函数相当于 匿名函数, 简化了函数的定义. 语言的发展 ...

  9. ES6中箭头函数的作用

    我们知道在ES6中,引入了箭头函数,其本质就是等同有ES5中的函数.类似于下面的写法: let test1=() => “abc”; let test2=() => { return “a ...

随机推荐

  1. BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)

    题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...

  2. Socks5代理Socks5 Proxy

    Socks5代理Socks5 Proxy   Socks5代理是基于Socks协议的一种代理模式.其中,5表示该协议的版本号.它可以让局域网的计算机通过socks5代理服务器,访问外网的内容.由于它工 ...

  3. Ubuntu 16.04下使用Wine安装Windows版的微信(不太完美)

    说明: 真的不太完美,别试了:除了需要安装额外的输入法之后,无法上传图片和间接性的BUG出现等等问题. 建议安装网页版的微信:http://www.cnblogs.com/EasonJim/p/711 ...

  4. Generate C and C++ Header File

    1. 2. 其中bootclasspath 后面的参数就是自己android.jar具体位置 location: ${system_path:javah} working Directoy: ${pr ...

  5. xamarin.IOS App闪退日志----crash

    一.查找日志文件位置:通过xcode/windows/device/你的IPhone/crash 二.拿到日志可以直接查看,但是日志记录太乱看不懂,需要转换处理,查找.DSYM文件,文件位置:/Use ...

  6. 全文索引-lucene,solr,nutch,hadoop之nutch与hadoop

    全文索引-lucene.solr.nutch,hadoop之lucene 全文索引-lucene.solr,nutch,hadoop之solr 我在去年的时候,就想把lucene,solr.nutch ...

  7. GDB调试多线程程序

    gdb有thread相关命令,如info thread(简写成info th)显示线程消息,b xx thread yy可以针对某个thread设置断点,thread xx(简写成thr xx)切换到 ...

  8. c++对象内存模型【内存布局】(转)

    总结:1.按1继承顺序先排布基于每个父类结构.2.该结构包括:基于该父类的虚表.该父类的虚基类表.父类的父类的成员变量.父类的成员变量.3.多重继承且连续继承时,虚函数表按继承顺序排布函数与虚函数.4 ...

  9. ListView中button监听器 设置 及 优化

    在应用开发中常常会用到ListView,而且每个Item里面都会有button之类的须要进行事件监听的控件.在给button加入OnClickListener的时候,一開始非常下意识的会想在ListV ...

  10. 绝不要在构造函数和析构过程中调用virtual函数

    下面是一个用来塑模股市交易的类: derived的类的构造函数被调用,但是首先得调用基类Transaction的构造函数,但是在后面还得调用virrual函数,这个时候子类的对象的构造还没有完成,那么 ...