默认渲染行为的问题

在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会在每次对原对象进行添加,删除,修改使返回新的对象实例。任何对数据的修改都会导致数据指针的变化。

其他的陷阱

需要注意的是,还有一些小陷阱需要避免。

  1. 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} />
)}
  1. 内联函数
    函数也经常作为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
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

 
===================
所以根据上述描述,以前在react中,使用箭头函数,虽然方便了函数的编写,但是会造成每次render都会渲染的问题!所以要改成在constructor函数中对函数绑定this。
注意的是,有些时候不可避免的要用到箭头函数或者在render中bind this 比如要传递参数时:
 
<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的作用及一些使用陷阱的更多相关文章

  1. Python进阶-II 参数陷阱、命名空间、嵌套、作用域、闭包

    一.参数陷阱 在使用默认参数时,可能碰见下列情况 def show_args_trap(i, li = []): li.append(100) li[i] = 101 print(li) show_a ...

  2. Java陷阱之assert关键字

    Java陷阱之assert关键字   一.概述   在C和C++语言中都有assert关键,表示断言. 在Java中,同样也有assert关键字,表示断言,用法和含义都差不多.   二.语法   在J ...

  3. ServiceStack.OrmLite中的一些"陷阱"(2)

    注:此系列不是说ServiceStack.OrmLite的多个陷阱,这仅仅个人认为是某一个陷阱(毕竟我踩坑了)而引发的思考. 前文说到了项目需要使用两种不同的数据库语言,虽说前文问题已基本解决了,但是 ...

  4. T-SQL中的一些小陷阱

    1,当心ISNULL函数对你的逻辑引起BUG 有人喜欢或者习惯于(并不代表我推荐,甚至这种写法没有任何好处)用ISNULL处理变量这种方式写查询 比如:select * from TestISNULL ...

  5. C# 中几个小“陷阱”

    每天写代码,偶尔就会有让你抓狂的时候:代码改了千百遍,蓦然回首,Bug就在灯火阑珊处……这里就列举一些容易犯错的几个小地方,以后遇到了其他的,再慢慢添加.   1. 获取程序当前运行路径   情景复现 ...

  6. 转:C/C++中,空数组、空类、类中空数组的解析及其作用

    转自:http://blog.sina.com.cn/s/blog_93b45b0f01015s95.html 我们经常会遇到这些问题: (1)C++中定义一个空类,他们它的大小(sizeof) 为多 ...

  7. ChannelOption.TCP_NODELAY, true->浅谈tcp_nodelay的作用

    在TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认.为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据.这里就涉及到一个名 ...

  8. [转]AngularJS: 使用Scope时的6个陷阱

    在使用AngularJS中的scope时,会有6个主要陷阱.如果你理解AngularJS背后的概念的话,这6个点其实非常的简单.但是在具体讲述这6个陷阱之前我们先要讲两个其它的概念. 概念1: 双向数 ...

  9. 【JavaScript】JavaScript中的陷阱大集合

    本文主要介绍怪异的Javascript,毋庸置疑,它绝对有怪异的一面.当软件开发者开始使用世界上使用最广泛的语言编写代码时,他们会在这个过 程中发现很多有趣的“特性”.即便是老练的Javascript ...

随机推荐

  1. day13-类的重写和类的私有方法

    类的重写 在python中 有时需要进行重写,重写是继承机制中的一个重要部分, 可以重写一般方法也可以重写构造方法,构造方法是用来初始化新创建对象的状态. class A : def hello(se ...

  2. oo作业总结(一)

    概述 经历了三次oo作业的洗礼,让我对java语言的强大以及面向对象编程有了初步的理解(当然,我是小白).本文接下来就将对自己这三次作业的代码进行分析以及分享自己的心路历程. 基础知识点考核 针对前三 ...

  3. OO第四次课程总结分析

    OO第四次课程总结分析 测试与正确性论证的效果差异及优缺点 测试,即使用测试样例来验证我们的程序是否能完成相应功能的过程.测试数据的产生基于前置条件和后置条件,通过执行测试数据检查方法输出是否满足需求 ...

  4. jquery 操作table样式拖动参考

    参考: http://blog.csdn.net/kdiller/article/details/6059727 http://www.jb51.net/article/59795.htm

  5. vue-router-9-HTML5 History 模式

    vue-router 默认 hash 模式,页面不会重新加载 用路由的 history 模式,利用 history.pushState API 来完成 URL 跳转而无须重新加载页面. const r ...

  6. sqlalchemy 简介

    #! /usr/bin/env python3 # -*- coding:utf-8 -*- #use SQLAlchemy #ORM:Object-Relational Mapping ,把关系数据 ...

  7. [Linux]Linux下yaf发送IPV4和IPV6的IPfix

    一.IPFIX与NetFlow 一.IPFIX 全称IP Flow Information Export,即IP流信息输出,是网络流量监测的国际标准.IPFIX是IETF的一个工作组,它的主要工作就是 ...

  8. java8新特性Lambda练习

    练习内容: 1.实现案例 /** *使用lambda表达式定义Collections.sort() */ /** *使用lambda表达式自定义比对方式 */ @Test public void Te ...

  9. 谷歌开源的TensorFlow Object Detection API视频物体识别系统实现(一)[超详细教程] ubuntu16.04版本

    谷歌宣布开源其内部使用的 TensorFlow Object Detection API 物体识别系统.本教程针对ubuntu16.04系统,快速搭建环境以及实现视频物体识别系统功能. 本节首先介绍安 ...

  10. SharePoint Framework 在Visual Studio Code中调试你的托管解决方案

    博客地址:http://blog.csdn.net/FoxDave 上一篇介绍了如何在本地调试你的SharePoint Framework解决方案,本篇介绍如何调试你的SharePoint Onl ...