在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结果。我已经定义User为PureComponent。所以只有当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容易出现问题的更多相关文章
- 在react jsx中使用if判断
在react jsx中如果使用if判断,需要这样做 var loginButton; if (loggedIn) { loginButton = <LogoutButton />; } e ...
- js中this,箭头函数和普通函数
四种基本用法 1. 一般方法中,this代指全局对象 window 2. 作为对象方法调用,this代指当前对象 3. 作为构造函数调用,this 指代new 出的对象 function test() ...
- JS中generater和箭头函数
generater跟函数很像: function* fn(x){ yield x; yield x++; return x;} 如上所示,generater用function*定义,可以用yield返 ...
- JS 函数(arguments、箭头函数、bind)
参数 函数内部可用的 arguments 对象来访问函数的实参 注意 在函数递归调用的时候(在某一刻同一个函数运行了多次,也就是有多套实参),那么 arguments 属性的值是最近一次该函数调用时传 ...
- es6中的双箭头函数
原代码: const fetchPosts = subreddit => dispatch => { dispatch(requestPosts(subreddit)); return c ...
- react jsx 中使用 switch case 示例
<div> <span>适用平台:</span> <span>{(() => { switch (currentItems.usePlatform ...
- 普通函数跟箭头函数中this的指向问题
箭头函数和普通函数的区别如下. 普通函数:根据调用我的人(谁调用我,我的this就指向谁) 箭头函数:根据所在的环境(我再哪个环境中,this就指向谁) 一针见血式总结: 普通函数中的this: 1. ...
- => js 中箭头函数使用总结
箭头函数感性认识 箭头函数 是在es6 中添加的一种规范 x => x * x 相当于 function(x){return x*x} 箭头函数相当于 匿名函数, 简化了函数的定义. 语言的发展 ...
- ES6中箭头函数的作用
我们知道在ES6中,引入了箭头函数,其本质就是等同有ES5中的函数.类似于下面的写法: let test1=() => “abc”; let test2=() => { return “a ...
随机推荐
- PythonWeb开发教程(二),搭建第一个django项目
这篇写怎么创建django项目,以及把django项目运行起来. 1.创建django项目 a.使用命令创建,安装完django之后就有django-admin命令了,执行命令创建即可,命令如下: ...
- spring的自动装配Bean与自动检测Bean
spring可以通过编写XML来配置Bean,也可以通过使用spring的注解来装配Bean. 1.自动装配与自动检测: 自动装配:让spring自动识别如何装配bean的依赖关系,减少对<pr ...
- 东方14ACM小组 15:Challenge 11
Challenge 11 查看 提交 统计 提问 总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 262144kB 描述 给一个长为N的数列,有M次操作,每次操作是 ...
- Unix domain socket
转载:http://www.cnblogs.com/chekliang/p/3222950.html socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是 ...
- android权限大全转http://www.cnblogs.com/classic/archive/2011/06/20/2085055.html
android权限大全转http://www.cnblogs.com/classic/archive/2011/06/20/2085055.html 访问登记属性 android.permission ...
- sql的一些知识_where
简单相同查询,查询age=22的三列信息,并按照降序排列 ORDER BY weight DESC 此外,where还支持一下判断操作符 值得注意的是,如果比较的值为数值,则不需要加引号,如果是字符, ...
- 百科知识 epub文件如何打开
.epub 简介 EPub是一个自由的开放标准,属于一种可以"自动重新编排"的内容:也就是文字内容可以根据阅读设备的特性,以最适于阅读的方式显示.EPub档案内部使用了XHTML或 ...
- Hibernate中的条件查询完毕类
Hibernate中的条件查询有下面三个类完毕: 1.Criteria:代表一次查询 2.Criterion:代表一个查询条件 3.Restrictions:产生查询条件的工具类
- vs项目添加链接文件
在vs2012(或以后版本)中,从一个项目中拖拽文件到另一项目,并按住alt键,会生成链接文件. 项目文件中会生成link节点. <ItemGroup> <Compile Inclu ...
- mqtt client python example
This is a simple example showing how to use the [Paho MQTT Python client](https://eclipse.org/paho/c ...