PureComponent的作用及一些使用陷阱
默认渲染行为的问题
在React Component的生命周期中,有一个shouldComponentUpdate方法。这个方法默认返回值是true。
这意味着就算没有改变组件的props或者state,也会导致组件的重绘。这就经常导致组件因为不相关数据的改变导致重绘,这极大的降低了React的渲染效率。比如下面的例子中,任何options的变化,甚至是其他数据的变化都可能导致所有cell的重绘。
//Table Component
{this.props.items.map(i =>
<Cell data={i} option={this.props.options[i]} />
)}
重写shouldComponentUpdate
为了避免这个问题,我们可以在Cell中重写shouldComponentUpdate方法,只在option发生改变时进行重绘。
class Cell extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
if (this.props.option === nextProps.option) {
return false;
} else {
return true;
}
}
}
这样每个Cell只有在关联option发生变化时进行重绘。
使用PureComponent与immutable.js
因为上面的情况十分通用,React创建了PureComponent组件创建了默认的shouldComponentUpdate行为。这个默认的shouldComponentUpdate行为会一一比较props和state中所有的属性,只有当其中任意一项发生改变是,才会进行重绘。
需要注意的是,PureComponent使用浅比较判断组件是否需要重绘
因此,下面对数据的修改并不会导致重绘(假设Table也是PureComponent)
options.push(new Option())
options.splice(0, 1)
options[i].name = "Hello"
这些例子都是在原对象上进行修改,由于浅比较是比较指针的异同,所以会认为不需要进行重绘。
为了避免出现这些问题,推荐使用immutable.js。immutable.js会在每次对原对象进行添加,删除,修改使返回新的对象实例。任何对数据的修改都会导致数据指针的变化。
其他的陷阱
需要注意的是,还有一些小陷阱需要避免。
- Literal Array与Literal Object
{this.props.items.map(i =>
<Cell data={i} options={this.props.options || []} />
)}
若options为空,则会使用[]。[]每次会生成新的Array,因此导致Cell每次的props都不一样,导致需要重绘。解决方法如下:
const default = [];
{this.props.items.map(i =>
<Cell data={i} options={this.props.options || default} />
)}
- 内联函数
函数也经常作为props传递,由于每次需要为内联函数创建一个新的实例,所以每次function都会指向不同的内存地址。比如:
render() {
<MyInput onChange={e => this.props.update(e.target.value)} />;
}
以及:
update(e) {
this.props.update(e.target.value);
}
render() {
return <MyInput onChange={this.update.bind(this)} />;
}
注意第二个例子也会导致创建新的函数实例。为了解决这个问题,需要提前绑定this指针:
constructor(props) {
super(props);
this.update = this.update.bind(this);
}
update(e) {
this.props.update(e.target.value);
}
render() {
return <MyInput onChange={this.update} />;
}
作者:橙子_80c3
链接:https://www.jianshu.com/p/33cda0dc316a
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
<ul>
{
list.map((item,index) => {
return (
<li key={index} onClick={()=>{deleteList(index)} }>{item}</li>
)
})
}
</ul>
注意上面,传递index时,箭头函数前面不要填写index,而在函数里面输入index。因为在函数前面的index相当于event了 onClick ={(index)=>{deleteList(index)}}
<ul>
{
list.map((item,index) => {
return (
<li key={index} onClick={deleteList.bind(this,index) }>{item}</li>
)
})
}
</ul>
PureComponent的作用及一些使用陷阱的更多相关文章
- Python进阶-II 参数陷阱、命名空间、嵌套、作用域、闭包
一.参数陷阱 在使用默认参数时,可能碰见下列情况 def show_args_trap(i, li = []): li.append(100) li[i] = 101 print(li) show_a ...
- Java陷阱之assert关键字
Java陷阱之assert关键字 一.概述 在C和C++语言中都有assert关键,表示断言. 在Java中,同样也有assert关键字,表示断言,用法和含义都差不多. 二.语法 在J ...
- ServiceStack.OrmLite中的一些"陷阱"(2)
注:此系列不是说ServiceStack.OrmLite的多个陷阱,这仅仅个人认为是某一个陷阱(毕竟我踩坑了)而引发的思考. 前文说到了项目需要使用两种不同的数据库语言,虽说前文问题已基本解决了,但是 ...
- T-SQL中的一些小陷阱
1,当心ISNULL函数对你的逻辑引起BUG 有人喜欢或者习惯于(并不代表我推荐,甚至这种写法没有任何好处)用ISNULL处理变量这种方式写查询 比如:select * from TestISNULL ...
- C# 中几个小“陷阱”
每天写代码,偶尔就会有让你抓狂的时候:代码改了千百遍,蓦然回首,Bug就在灯火阑珊处……这里就列举一些容易犯错的几个小地方,以后遇到了其他的,再慢慢添加. 1. 获取程序当前运行路径 情景复现 ...
- 转:C/C++中,空数组、空类、类中空数组的解析及其作用
转自:http://blog.sina.com.cn/s/blog_93b45b0f01015s95.html 我们经常会遇到这些问题: (1)C++中定义一个空类,他们它的大小(sizeof) 为多 ...
- ChannelOption.TCP_NODELAY, true->浅谈tcp_nodelay的作用
在TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认.为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据.这里就涉及到一个名 ...
- [转]AngularJS: 使用Scope时的6个陷阱
在使用AngularJS中的scope时,会有6个主要陷阱.如果你理解AngularJS背后的概念的话,这6个点其实非常的简单.但是在具体讲述这6个陷阱之前我们先要讲两个其它的概念. 概念1: 双向数 ...
- 【JavaScript】JavaScript中的陷阱大集合
本文主要介绍怪异的Javascript,毋庸置疑,它绝对有怪异的一面.当软件开发者开始使用世界上使用最广泛的语言编写代码时,他们会在这个过 程中发现很多有趣的“特性”.即便是老练的Javascript ...
随机推荐
- java中方法内可以调用同一个类中的方法
在同一个类中,java的普通方法的相互调用,可以使用this+点号+方法名,也可省略this+点号,java编 译器会自动补上.
- TagHelpers 使用
@using AuthoringTagHelpers @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers // 手动高亮
- net core 获取网站目录
AppContext.BaseDirectory 获取项目的根目录
- linux系统安装jdk详细配置
1.通过指令 whereis java 查看是否已经配置jdk 如果已经安装,通过指令 rm -rf <jdk路径> 删除 2.通过ssh工具将jdk-8u11-linux-x64.tar ...
- idea没有错误出现红色波浪线怎么去掉?
在有波浪线的代码上Alt+Enter,弹出的菜单中第一项的子菜单选择disable inspection
- ssh 免密登陆
A 要免密码登录要B 那么需要在A电脑上使用命令 ssh-keygen -t rsa 在~/.ssh/ 目录下生成id_rsa.pub 这个文件,然后将这个文件的内容拷到B电脑de ~/.ssh/au ...
- Android 删除图片等资源文件 通知系统更新,重新扫描
public void delPic(String path){ File delFile = new File(path); if (delFile.exists()) { delFile.dele ...
- 基于spec互评Alpha版本
作业要求[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2323] 队名:二次元梦之队 组长:刘莹莹 组员:周昊 潘世维 王玉潘 赵美增 ...
- [Spring-AOP-XML] 利用Spirng中的AOP和XML进行事务管理
Spring中的AOP进行事务管理有三种方式 A.自定义事务切面 利用AspectJ来编写事务,我们一般把这个切面作用在service层中.其他代码在下面 编写一个Transaction实现类,通过S ...
- vue简章
什么是vue? 可以独立完成前后端分离式web项目的javaScript框架 为什么使用vue? 三大主流框架之一:Angular React Vue 先进的前端设计模式:MVVM 可以完全脱离服务 ...