什么是 Impure Component

Flink流处理
• 阅读 2744

在优化 React 组件的时候我们常常会看到 Pure Component 的说法,所谓 Pure Component 就是在 props,state 和 context 不变的情况下,组件的 render 结果也是不变的。基于这个前提,我们可以很方便地用 shouldCompoentUpdate 来优化组件,减少 render。

import React, { Component } from 'react';
import shallowequal from 'shallowequal';

class FullName extends Component {
  shouldComponentUpdate(nextProps) {
    return !shallowequal(this.props, nextProps)
  }

  render() {
    const { firstName, lastName } = this.props;

    return (
      <div>{firstName} {lastName}</div>
    )
  }
}

React 官方也提供了 PureRenderMixin (给 React.createClass 用)和 React.PureComponent 来让我们方便地声明一个 Pure Component。

那么既然有 Pure Component 的说法,肯定还有相对的 Impure Component。一言以蔽之,只要你的组件依赖了 props 和 state (context 比较特殊,后面会讲到)之外的数据,你的组件就不是 pure 的,我们来看例子。

例子一

class FullName extends Component {
  render() {
    const { firstName, lastName } = this.props;

    return (
      <div>{firstName} {lastName} - {new Date}</div>
    )
  }
}

我们在这里增加了一个当前日期的显示,导致即使 firstName 和 lastName 不变化,组件每次 render 的结果也是不同的,这个组件就没办法用 shouldCompoentUpdate 去优化了。

例子二

class App extends Component {
  state = {
    lastName: '',
  }

  handleChange = e => {
    this.setState({ lastName: e.target.value });
  }

  renderLastName = () => {
    return this.state.lastName;
  }

  render() {
    <div>
      <input type="text" onChange={this.handleChange} />
      <FullName firstName="Ava" lastName={this.renderLastName} />
    </div>
  }
}


class FullName extends Component {
  render() {
    const { firstName, lastName } = this.props;

    return (
      <div>{firstName} {lastName()}</div>
    )
  }
}

这个例子我们把 lastName 变成一个方法传进来,这样其实 FullName 组件通过闭包,而不是通过 props,依赖了 App 的 state.lastName ,导致在 firstName 和 lastName 都不变化的情况下,FullName 会根据 state.lastName 的不同 render 出不同的结果。

例子三

class App extends Component {
  static childContextTypes = {
    firstName: React.PropTypes.string,
    lastName: React.PropTypes.string,
  }

  getChildContext() {
     return {
       firstName: 'Taylor',
       lastName: 'Swift',
     };
  }

  render() {
    <Segment>
      <FullName />
    </Segment>
  }
}

class Segment extends Component {
  render() {
    <div>{this.props.children}</div>
  }
}

class FullName extends Component {
  static contextTypes = {
    firstName: React.PropTypes.string,
    lastName: React.PropTypes.string,
  };

  render() {
    const { firstName, lastName } = this.context;

    return (
      <div>{firstName} {lastName}</div>
    )
  }
}

这个例子其实算是 React 留给我们的一个,这里 FullName 是 Pure Component,但是 Segament 却不是,因为 Segament 的 render 结果间接地依赖了上层的 context。

点赞
收藏
评论区
推荐文章
爱丽丝13 爱丽丝13
4年前
React 组件通信之发布订阅模式
React通信react的数据流是单向的,react通信有以下几种方式:父向子通信:传入props子向父通信:父组件向子组件传一个函数,然后通过这个函数的回调,拿到子组件传过来的值父向孙通信:利用context传值。React.createContext()兄弟间通信:​1、找一个相同的父组件,既可以用pr
爱丽丝13 爱丽丝13
4年前
快速了解 React Hooks 原理
为了保证的可读性,本文采用意译而非直译。我们大部分React类组件可以保存状态,而函数组件不能?并且类组件具有生命周期,而函数组件却不能?React早期版本,类组件可以通过继承PureComponent来优化一些不必要的渲染,相对于函数组件,React官网没有提供对应的方法来缓存函数组件以减少一些不必要的渲染,直接16.6出来的Rea
亚瑟 亚瑟
4年前
自定义 Hook – React
自定义Hook_Hook_是React16.8的新增特性。它可以让你在不编写class的情况下使用state以及其他的React特性。通过自定义Hook,可以将组件逻辑提取到可重用的函数中。在我们学习时,我们已经见过这个聊天程序中的组件,该组件用于显示好友的在线状态:importReact,{useSta
徐小夕 徐小夕
4年前
《彻底掌握redux》之开发一个任务管理平台(上)
前言redux是上手react开发的必经之路,也是目前react项目中使用的最流行状态管理库。虽然我们不使用redux也可以通过react的state和父子props进行基本的数据通信和项目开发,但是对于一个大型项目而言,往往考虑的更多的是代码结构和组件之间的通信,我们需要一种很优雅且有利于扩展的方式去开发我们的复杂系统,所以这种情况下使用redux是最佳
Stella981 Stella981
3年前
React动画:react
1.安装yarnaddreacttransitiongroup2.使用CSSTransition组件importReact,{PureComponent}from'react';import{
Wesley13 Wesley13
3年前
RN这个神操作,客官了解一下
在reactnative中我们可以通过setNativeProps直接改动组件并触发局部刷新,不用使用props或state.对此,官方的说明以及使用场景:什么时候使用setNativeProps呢?在(不得不)频繁刷新而又遇到了性能瓶颈的时候。直接操作组件并不是应该经常使用的工具。一般来说只是用来创建连续的动画,同时避免渲染组件结构和同步
Stella981 Stella981
3年前
React.js 时间组件 + 组件生命周期(更新模拟)
React是用于构建用户界面的JavaScript库,React组件使用一个名为render()的方法,接收数据作为输入,输出页面中对应展示的内容。React除了可以使用外部传入的数据以外(通过this.props访问传入数据),组件还可以拥有其内部的状态数据(通过this.state访问状态数据)。当组件的状态
Stella981 Stella981
3年前
React_PureComponent 简化 react shouldComponentUpdate 方法,优化性能
PureComponent 与 Component 类似,自react 15.3版本之后使用,主要为了提高组件的重复加载问题,提高性能,类似于shouldComponentUpdate功能。importReact,{Component,PureCompoent} from'react'classAextendsPure
Stella981 Stella981
3年前
React 第一个小游戏(井字棋)知识关键点
1、React是一个声明式,高效且灵活的用于构建用户界面的JavaScript库通过使用组件来告诉React我们希望在屏幕上看到什么。当数据发生变化时,React会高效的更新并重新渲染我们的组件2、render返回了一个React元素,这是一种对渲染内容的轻量级描述。大多数的React开发者使用了一种名为"JSX"的特
Stella981 Stella981
3年前
React.js 组件的 props vs state
看到一篇无比蛋疼的文章:https://www.oschina.net/translate/exploringreactsstatepropagation(https://www.oschina.net/translate/exploringreactsstatepropagation)。我不针对翻译,只是针对这篇文章想提出的概念,说了跟没说
React memo的原理、实践与思考
前言在react中,对一个组件进行点击事件等操作时,该组件以及该组件的子组件都会重新渲染。避免组件的重新渲染一般可以借助React.memo、useCallback等来实现。什么是memomemo原理memo类似于class中pureComponent的特