react与mox-react的shouldComponentUpdate 理解
react性能优化中,提到的就是通过 React.PureComponent 替换 React.Component 组件进行编程。
两个组件之间的不同主要就是PureComponent做了shouldComponentUpdate的优化。对props和state进行了第一层的值===比较, 并且对 context 的变化不进行判断。
通过查看React可以看到
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @typechecks
*
*/ /*eslint-disable no-self-compare */ 'use strict'; var hasOwnProperty = Object.prototype.hasOwnProperty; /**
* inlined Object.is polyfill to avoid requiring consumers ship their own
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
*/
function is(x, y) {
// SameValue algorithm
if (x === y) {
// Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
// Added the nonzero y check to make Flow happy, but it is redundant
return x !== 0 || y !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
} /**
* Performs equality by iterating through keys on an object and returning false
* when any key has values which are not strictly equal between the arguments.
* Returns true when the values of all keys are strictly equal.
*/
function shallowEqual(objA, objB) {
if (is(objA, objB)) {
return true;
} if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
return false;
} var keysA = Object.keys(objA);
var keysB = Object.keys(objB); if (keysA.length !== keysB.length) {
return false;
} // Test for A's keys different from B.
for (var i = 0; i < keysA.length; i++) {
if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
return false;
}
} return true;
} module.exports = shallowEqual;
shallowEqual
项目准备升级 React16,控制台出现了错误 shouldComponentUpdate should not be used when extending React.PureComponent.
一开始看很莫名其妙,明明组件没有自己写shouldComponentUpdate,怎么就报错了。
后来谷歌了下,原来是项目使用了mobx进行的状态管理。使用mox-react,对所有组件都通过 @observer 装饰器,以前也看过mobx-react源码,里面的确mixin了shouldComponentUpdate方法,优化了组件的性能
看下面的源代码
function mixinLifecycleEvents(target) {
patch(target, "componentWillMount", true)
;["componentDidMount", "componentWillUnmount", "componentDidUpdate"].forEach(function (
funcName
) {
patch(target, funcName)
})
if (!target.shouldComponentUpdate) {
target.shouldComponentUpdate = reactiveMixin.shouldComponentUpdate
}
}
{
shouldComponentUpdate: function(nextProps, nextState) {
if (isUsingStaticRendering) {
console.warn(
"[mobx-react] It seems that a re-rendering of a React component is triggered while in static (server-side) mode. Please make sure components are rendered only once server-side."
)
}
// update on any state changes (as is the default)
if (this.state !== nextState) {
return true
}
// update if props are shallowly not equal, inspired by PureRenderMixin
// we could return just 'false' here, and avoid the `skipRender` checks etc
// however, it is nicer if lifecycle events are triggered like usually,
// so we return true here if props are shallowly modified.
return isObjectShallowModified(this.props, nextProps)
}
}
function isObjectShallowModified(prev, next) {
if (null == prev || null == next || typeof prev !== "object" || typeof next !== "object") {
return prev !== next
}
const keys = Object.keys(prev)
if (keys.length !== Object.keys(next).length) {
return true
}
let key
for (let i = keys.length - 1; i >= 0, (key = keys[i]); i--) {
if (next[key] !== prev[key]) {
return true
}
}
return false
}
经过测试,使用setState后,shouldComponentUpdate 的确 this.state!==nextState,但是对于this.props, nextProps的判断,还是存在一些差别的。
可以试下下面的比较
console.log(isObjectShallowModified(NaN, NaN), !shallowEqual(NaN, NaN));
var a = {a: 1}, b = {b: 1, __proto__: {a: 1}};
console.log(isObjectShallowModified(a, b), !shallowEqual(a, b));
对于一些比较简单的对象比较结果还是相同的,所以对于@observer的组件就改为了React.Component进行处理。
react与mox-react的shouldComponentUpdate 理解的更多相关文章
- 【React】383- React Fiber:深入理解 React reconciliation 算法
作者:Maxim Koretskyi 译文:Leiy https://indepth.dev/inside-fiber-in-depth-overview-of-the-new-reconciliat ...
- 手写React的Fiber架构,深入理解其原理
熟悉React的朋友都知道,React支持jsx语法,我们可以直接将HTML代码写到JS中间,然后渲染到页面上,我们写的HTML如果有更新的话,React还有虚拟DOM的对比,只更新变化的部分,而不重 ...
- React 之 高阶组件的理解
1.基本概念 高阶组件是参数为组件,返回值为新组件的函数. 2.举例说明 ① 装饰工厂模式 组件是 react 中的基本单元,组件中通常有一些逻辑(非渲染)需要复用处理.这里我们可以用高阶组件对组件内 ...
- react系列从零开始-react介绍
react算是目前最火的js MVC框架了,写一个react系列的博客,顺便回忆一下react的基础知识,新入门前端的小白,可以持续关注,我会从零开始教大家用react开发一个完整的项目,也会涉及到w ...
- [React] 从零开始的react
组件 1. 无状态组件 在React中,组件的名字必须用大写字母开头,而包含该组件定义的文件名也应该是大写字母(便于区分,也可以不是). 无状态组件是纯展示组件,仅仅只是用于数据的展示,只根据传入的p ...
- React 学习(一) ---- React Element /组件/JSX
学习React的时候,你可能听到最多的就是要先学习webpack, babel,要先学会配置然后才能学react 等等,一堆的配置就把我们吓着了,根本就没有心情就学习react了.其实在最开始学习re ...
- React.Component 与 React.PureComponent(React之性能优化)
前言 先说说 shouldComponentUpdate 提起React.PureComponent,我们还要从一个生命周期函数 shouldComponentUpdate 说起,从函数名字我们就能看 ...
- React Native之React速学教程(下)
概述 本篇为<React Native之React速学教程>的最后一篇.本篇将带着大家一起认识ES6,学习在开发中常用的一些ES6的新特性,以及ES6与ES5的区别,解决大家在学习Reac ...
- react新特性 react hooks
本文介绍的是react新特性react hooks,本文面向的是有一定react开发经验的小伙伴,如果你对react还不是很熟悉的话我建议你先学习react并多多联系. 首先我们都知道react有3种 ...
随机推荐
- ioctl函数用法小记
By francis_hao Aug 27,2017 UNPV1对ioctl有算是比较详细的介绍,但是,这些request和后面的数据类型是从哪里来的,以及参数具体该如何使用呢?本文尝试在不 ...
- ACE线程管理机制-并发控制(1)
转载于:http://www.cnblogs.com/TianFang/archive/2006/12/04/581771.html ACE Lock类属 锁类属包含的类包装简单的锁定机制,比如互斥体 ...
- 为什么使用centos部署服务器
这个是实验室同学面试的时候,面试官问的一个问题? 为什么选择centos系统,为什么centos系统用的比较多呢? 首先我们说下redhat红帽公司,它是全球最大的linux服务提供商,它的服务是最好 ...
- redis 查看所有键值
zb@zb-computer:/home/wwwroot/default/lion/Admin$ /usr/local/redis/bin/redis-cli 127.0.0.1:6379> k ...
- [LeetCode] 3. Longest Substring Without Repeating Characters ☆☆☆
Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...
- 用pip命令安装Python第三方库
一.准备工作 1. 安装pip (1)下载 pip下载地址:https://pypi.python.org/pypi/pip#downloads (2)安装 下载后解压,控制台下进入解压后的目录,运行 ...
- [uva11997]k个最小和
一个k*k的矩阵,每行选取一个数相加则得到一个和,求最小的前k个和. k<=750 已知前m行最小的前k个和d[1]…d[k],则前m+1行最小的前k个和都必定是d[i](i<=k)+a[ ...
- 【LibreOJ】#541. 「LibreOJ NOIP Round #1」七曜圣贤
[题意]一开始车上有编号为0~a的红茶,过程中出现的红茶编号仅有[0,b),有三种操作: 1.买进编号未在车上出现过的红茶. 2.丢掉车上指定编号的红茶. 3.将最早丢出去的红茶捡回来. 每次操作后求 ...
- 快速搭建 DNS 服务器: skydns + etcd
参考: [ skynetservice github ] [ skydns 测试记录 CSDN ] etcd 安装配置 安装 yum install etcd 配置 sed -i 's@ETCD_LI ...
- Spring Boot 中使用 MyBatis 整合 Druid 多数据源
2017 年 10 月 20 日 Spring Boot 中使用 MyBatis 整合 Druid 多数据源 本文将讲述 spring boot + mybatis + druid 多数据源配置方 ...