什么是shouldComponent?

  1. React中的一个生命周期,
  2. 运行时机:在getDerivedStateFromProps之后,render之前执行
  3. 触发条件:
    a. props更新
    b. setState

forceUpdate不会导致shouldComponentUpdate的触发

  1. 作用,如果返回true,那组件就继续render;如果返回false,组件就不更新渲染

什么是pureComponent

  1. React的一种组件类;
  2. 与React.Component很相似。两者的区别在于React.Component中,并没有实现shouldComponentUpdate,需要继承类自己实现。而React.PureComponent中,会浅层对比prop和state,如果内容相同,那么组件将会跳过此次的render更新;
  3. React.PureComponent 中的 shouldComponentUpdate() 将跳过所有子组件树的 prop 更新。因此,请确保所有子组件也都是“纯”的组件。

纯组件的含义,就是传入相同的props对象,总会有相同的渲染内容。

类似于 纯函数 的定义

4.判断步骤:
如果 PureComponent 里有 shouldComponentUpdate 函数的话,直接使用 shouldComponentUpdate 的结果作为是否更新的依据。

没有 shouldComponentUpdate 函数的话,才会去判断是不是 PureComponent ,是的话再去做 shallowEqual 浅比较。

 const instance = workInProgress.stateNode;
// 如果实利实现了shouldComponentUpdate则返回调用它的结果
if (typeof instance.shouldComponentUpdate === 'function') {
    const shouldUpdate = instance.shouldComponentUpdate(
        newProps,
        newState,
        nextContext,
    return shouldUpdate;
// PureReactComponent的时候进行浅对比
if (ctor.prototype && ctor.prototype.isPureReactComponent) {
    return (
        !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)
 

从上面的代码就可以看出,pureComponent不是实现了shouldComponentUpdate的Component,而是在对比的时候就返回浅对比的结果。

  1. PureComponent不可滥用,他使用在class组件内,只有那些状态和属性不经常的更新的组件我们用来做优化,对于经常更新的,这样处理后反而浪费性能,因为每一次浅比较也是要消耗时间的

什么是shallowEqual浅比较

这里有写得很不错的文章:浅谈React 中的浅比较是如何工作的

我总结一下这片文章里面写的东西:

  • 浅比较的对象,是新旧两个props、新旧两个state
// PureReactComponent的时候进行浅对比
  if (ctor.prototype && ctor.prototype.isPureReactComponent) {
    return (
      !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)
  • 先判断两个对象是否地址相同。如果地址相同,就直接返回true;如果地址不相同,就继续判断

网上很多文章把第一步的意义判定为,基本类型的相等性判断

  • 再判断有没有不是对象的值,或者等于null的值。如果有,直接返回false;如果没有,就继续判断

只有这一步通过了,下面的判断才有了意义

如果把第一步判定为,基本类型的判断,那第二步又如何解释呢?

话又说回来了,传进来的props或者state一定是对像啊。如果传进来的是非对象,又是怎么做到的呢?

  • 再判断两个props的key数量,是否相同,如果相同就继续下一步的判断;如果不相同,就直接返回false
  • 最后一步,分别判断每个key对应的value值,是否相同。判断value是否相同,使用的是object.is()

此处附上shallowEqual的源码

// shallowEqual.js
function shallowEqual(objA: mixed, objB: mixed): boolean {
    // 一样的对象返回true
    if (Object.is(objA, objB)) {
        return true;
    // 不是对象或者为null返回false
        typeof objA !== 'object' || objA === null ||
        typeof objB !== 'object' || objB === null
        return false;
    const keysA = Object.keys(objA);
    const keysB = Object.keys(objB);
    // key数量不同返回false
    if (keysA.length !== keysB.length) {
        return false;
    // 对应key的值不相同返回false
    for (let i = 0; i < keysA.length; i++) {
            !hasOwnProperty.call(objB, keysA[i]) ||
            !Object.is(objA[keysA[i]], objB[keysA[i]])
            return false;
    return true;

什么是React.memo

const MyComponent = React.memo(function MyComponent(props) {
  /* 使用 props 渲染 */
},areEqual); 
  1. React.memo是高阶组件,

  2. 包裹其中的组件,并返回新的组件。该组件在props没有变更的时候,就会返回相同的渲染结果,也就是直接跳过渲染阶段。该阶段及其之后的阶段的生命周期函数就不会得到调用。当然,进行的也是浅比较

  3. 用法:

    1. 第一个参数,是函数组件( React.FunctionComponent)
    2. 第二个参数,回调函数。如果我们觉得浅比较不行,我们就填入第二个参数,React会把第二个参数的返回值,当作是否跳过更新的标准
function areEqual(prevProps, nextProps) {
  如果把 nextProps 传入 render 方法的返回结果与
  将 prevProps 传入 render 方法的返回结果一致则返回 true,
  否则返回 false
  1. 与 class 组件中 shouldComponentUpdate() 方法不同的是,如果 props 相等,areEqual 会返回 true;如果 props 不相等,则返回 false。这与 shouldComponentUpdate 方法的返回值相反

这个要引起我们的注意

这是react为跳过子组件更新而做出的努力

  1. 生命周期函数 shouldComponentUpdate
  2. Component类,React.pureComponent
  3. Memo
@miblanchard/react-native-slider 用于 react-native 和 react-native-web 的<Slider>组件的纯 JavaScript 版本。 这可以直接替换来自 react-native/@react-native-community 的 Slider 组件。 非常欢迎想法和贡献。 yarn add @miblanchard/react-native-slider npm i --save @miblanchard/react-native-slider 1.xx 版本只支持 React Native >= 0.59.0 React Native 版本 支持 react-native-slider 版本 v0.59.0+ v1.xx import React from "react" ; < Calendar xss=removed xss=removed> setSelectDate ( date ) } onSelectDates = { dates => setSelectDates ( dates ) } selectDate = { selectDate } selectDates = { selectDates } beforeDisablePoint = { beforeDisablePoint } afterDisablePoint = { afterDisablePoint } disableDates = { disableDates } onSelectDate ([日期,数字])=> {} 选择单元格时的选定日期 ()=> {} onSelectDates React惰性负载组件 React Lazy Load是易于使用的React组件,可帮助您以可预测的方式推迟加载内容。 它速度很快,可在IE8 +中运行,最小化为6KB,默认情况下使用去抖动功能。 您还可以在滚动容器内使用组件,例如带有滚动条的div。 它会自动找到。 看看一个例。 React Lazy Load需要React 0.14或更高版本。 npm install --save react-lazy-load import React from 'react' ; import LazyLoad from 'react-lazy-load' ; const MyComponent = ( ) => ( Scroll to load images. < div xss=removed> import React from "react" ; import { render } from "react-dom" ; import AceEditor from "react-ace" ; import "ace-builds/src-noconflict/mode- 如果父组件的state发生变化,那么就需要重新render。其下的组件即使没有用到此state,也会跟着重新render。性能受影响。 现有方法 react.memo 能实现,只有当组件的 props里的数据发生变化后,才会重新render。 注:此方法是浅比较。 父组件的input框输入的时候,会引起 inp_value 的变化。必然引起父组件的重新render。但是此时并没有引起组件的render export default function Reactuse() { 这样判断 就会监听到 cont 到底有没有改变 如果改变了 则重新渲染 如果完全相等 那就表示没有改变 就返回false 阻止渲染。首先 我们在父组件中定义了一个cont响应式数据 然后 在componentDidMount生命周期中定义了一个定时器 改变cont。但这样显然是有问题的 因为这样 当组件关联的数据改变时 我们这样写死 返回false 他就不渲染了。这里 我们知道 当父组件数据改变时 组件也会被重新渲染。定时器跑几下 我们就看出不对了。 state更新,用setState()更新即可在componentWillReceiveProps()生命周期中更新 componentWillReceiveProps(nextProps){ this.setState({ data: nextProps.data props更新,这种情况适 最近遇到一个问题,在父组件那里渲染后,在组件中setState和forceUpdate都不能刷新组件数据,最后使用下面方式解决了这个问题: // 父组件中 { childrenVisible ? <ChildrenCoponent dispatch={dispatch} visible={childrenVisible } /> : null