GVKun编程网logo

在没有shouldComponentUpdate的情况下,React 0.14的无状态组件将如何提高性能?

14

如果您想了解在没有shouldComponentUpdate的情况下,React0.14的无状态组件将如何提高性能?的知识,那么本篇文章将是您的不二之选。同时我们将深入剖析linux–如何在没有Seg

如果您想了解在没有shouldComponentUpdate的情况下,React 0.14的无状态组件将如何提高性能?的知识,那么本篇文章将是您的不二之选。同时我们将深入剖析linux – 如何在没有Segmentation错误的情况下在Google Compute Engine上运行R.、React 函数式无状态组件,PureComponent,Component;有什么区别,我们什么时候应该使用什么?、react 如何通过 shouldComponentUpdate 来减少重复渲染、react 常见组件问题 Can''t perform a React state update on an unmounted component的各个方面,并给出实际的案例分析,希望能帮助到您!

本文目录一览:

在没有shouldComponentUpdate的情况下,React 0.14的无状态组件将如何提高性能?

在没有shouldComponentUpdate的情况下,React 0.14的无状态组件将如何提高性能?

自从我阅读了有关React
0.14的发行说明(以及其他相关炒作)以来,这个问题一直困扰着我-我是React的忠实拥护者,我认为无状态组件(https://facebook.github。 io / react / blog /
2015/09/10 / react-v0.14-rc1.html#stateless-function-
components)是一个极好的主意,既便于编写此类组件,又可以在代码中表达这些意图就相同道具数据的一致渲染而言,组件应该是“纯”的。

现在的问题是:怎么会有可能发生反应,优化这些无国籍组件功能没有去整猪,并假设道具引用这不仅表现在他们不应该在组件内操纵一成不变的,但 也是
他们永远无法改变在组件生命周期之外?“常规”组件(又称有状态组件,即贯穿整个生命周期的组件;
componentWillMount,getInitialState等)具有可选的“ shouldComponentUpdate”功能的原因是,React
不会
假设所有道具和状态引用都是完全不变的。渲染组件后,道具引用的某些属性可能会更改,因此相同的“道具”实例稍后可能会具有不同的内容。这部分是为什么对完全不可变结构的使用感到非常兴奋,以及为什么有人说将Om与React一起使用可以带来巨大的性能提升的原因;因为在那里使用的不可变结构保证了任何对象的任何给定实例都不会被突变,所以ComponentUpdate应该可以对props和state执行非常便宜的引用相等性检查(http://swannodette.github.io/2013/12/17/the
-future-of-javascript-mvcs /)。

我一直在尝试寻找有关此的更多信息,但是却一无所获。我无法设想什么性能的提升 可以 进行围绕无状态组件
假定该道具的数据将包括不变类型的..也许非一成不变的道具类型的一些初步的分析,试图猜测是否“道具”和“nextProps”代表相同的数据?

我只是想知道是否有人对此有任何内部信息或其他启发性的见解。如果React 确实
开始要求props类型是“完全不可变的”(允许进行引用相等性比较以确认数据没有更改),那么我认为这将是向前迈出的一大步,但这也可能是一个巨大的变化。

答案1

小编典典

避免不必要的分配

如果我理解正确,无状态功能组件将转换为常规组件。从来源:

function StatelessComponent(Component) {}StatelessComponent.prototype.render = function() {  var Component = ReactInstanceMap.get(this)._currentElement.type;  return Component(this.props, this.context, this.updater);};

创建无状态组件的实例时,将分配一个新对象。这个新对象具有生命周期方法,例如componentWillMountcomponentWillReceiveProps。我猜想该计划根本
创建这些对象。 不创建对象将避免不必要的分配。

避免不必要的检查

实现生命周期方法需要进行如下检查:

if (inst.componentWillUpdate) {  inst.componentWillUpdate(nextProps, nextState, nextContext);}

可以假定无状态功能组件没有这些生命周期方法。那可能就是文档所指的,但我不确定。

编辑

删除了记忆中的内容,这些内容无法回答问题或无法很好地解释内容。

linux – 如何在没有Segmentation错误的情况下在Google Compute Engine上运行R.

linux – 如何在没有Segmentation错误的情况下在Google Compute Engine上运行R.

我正在尝试使用Google的计算引擎来运行R,但仍会遇到分段错误.这是我到目前为止所做的:

1)我安装了Cygwin& Google Cloud SDK已成功通过Google云端平台验证.

2)我使用谷歌提供的“debian-7-wheezy-v20140318”图像和“n1-standard-4”机器创建了一个虚拟机.

3)我已使用命令在此虚拟机上安装了R(使用add’l软件)

sudo apt-get update
sudo apt-get install -y libopenblas-base openmpi-bin libopenmpi-dev r-base openjdk-7-jre openjdk-7-jdk

4)我已经使用该命令验证了软件是否已安装

apt-cache policy r-base

返回安装v2.15.1-4.

每次我尝试提交一个简单的R脚本来安装一些常见的R包(通过命令“sudo R CMD BATCH –no-save installrpkgs.R”),输出日志给我错误

Segmentation fault

当我ssh到虚拟机尝试显式运行R时,我也得到相同的错误.我有一种感觉,我错过了一些东西.也许我需要指定内存或写权限.我不确定,因为我还是云计算的新手.如果有人能帮助所有人,我会非常感激.

谢谢!

编辑:
经过一些故障排除后,我设法确定罪魁祸首是“libopenblas-base”.不知道为什么会造成这种情况,但是现在我只是继续没有它.

解决方法

您可以安装软件包’strace’,然后运行’sudo strace R CMD BATCH –no-save installrpkgs.R’来查看调用的内容及其退出状态.不幸的是,我不熟悉你所遇到的问题,但是当程序本身几乎没有输出时,strace可以非常有助于找出问题所在.

React 函数式无状态组件,PureComponent,Component;有什么区别,我们什么时候应该使用什么?

React 函数式无状态组件,PureComponent,Component;有什么区别,我们什么时候应该使用什么?

得知从 React v15.3.0 开始 ,我们有一个名为 PureComponent 的新基类,可以使用内置的
PureRenderMixin 进行扩展。我的理解是,在引擎盖下,这采用了内部道具的浅显比较shouldComponentUpdate

现在我们有 3 种方法来定义 React 组件:

  1. 不扩展任何类的功能性无状态组件
  2. 扩展PureComponent类的组件
  3. Component扩展类的普通组件

前段时间,我们曾经将无状态组件称为纯组件,甚至是哑组件。似乎“纯”这个词的整个定义现在在 React 中已经改变了。

尽管我了解这三者之间的基本区别,但我仍然不确定 何时选择什么 。另外,每种方法的性能影响和权衡是什么?


更新

这些是我希望得到澄清的问题:

  • 我应该选择将我的简单组件定义为功能性(为了简单起见)还是扩展PureComponent类(为了性能)?
  • 我获得的性能提升是否是我失去的简单性的真正权衡?
  • Component当我总是可以使用PureComponent以获得更好的性能时,我是否需要扩展普通类?

答案1

小编典典

您如何决定,如何根据我们组件的用途/大小/道具/行为在这三者之间进行选择?

从自定义方法扩展React.PureComponent或从React.Component自定义shouldComponentUpdate方法扩展具有性能影响。使用无状态功能组件是一种“架构”选择,并且没有任何开箱即用的性能优势(目前)。

  • 对于需要轻松重用的简单、仅展示的组件,更喜欢无状态的功能组件。通过这种方式,您可以确定它们与实际的应用程序逻辑分离,它们非常容易测试并且它们没有意外的副作用。例外情况是,如果由于某种原因你有 很多 ,或者你真的需要优化它们的渲染方法(因为你不能shouldComponentUpdate为无状态功能组件定义)。

  • 如果您知道您的输出取决于简单的道具/状态(“简单”意味着没有嵌套数据结构,因为PureComponentPureComponent执行浅比较)并且您需要/可以获得一些性能改进,请扩展。

  • 如果您需要通过在下一个/当前道具和状态之间执行自定义比较逻辑来获得一些性能提升,请扩展Component和实现您自己的。shouldComponentUpdate例如,您可以使用 lodash#isEqual 快速执行深度比较:

    class MyComponent extends Component {shouldComponentUpdate (nextProps, nextState) {    return !_.isEqual(this.props, nextProps) || !_.isEqual(this.state, nextState);}

    }

此外,实现自己的shouldComponentUpdate或扩展的PureComponent都是优化,并且像往常一样,只有在遇到性能问题时才应该开始研究(避免过早的优化)。根据经验,我总是在应用程序处于工作状态后尝试进行这些优化,并且大多数功能已经实现。当性能问题真正阻碍时,专注于性能问题要容易得多。

更多细节

功能性无状态组件:

这些只是使用函数定义的。由于无状态组件没有内部状态,因此输出(渲染的内容)仅取决于作为该函数输入的道具。

优点:

  • 在 React 中定义组件的最简单方法。如果您不需要管理任何状态,为什么还要为类和继承而烦恼呢?函数和类之间的主要区别之一是,通过函数,您可以确定输出仅取决于输入(而不取决于先前执行的任何历史记录)。

  • 理想情况下,在您的应用程序中,您的目标应该是拥有尽可能多的无状态组件,因为这通常意味着您将逻辑移到视图层之外并将其移至 redux 之类的东西,这意味着您可以测试您的真实逻辑而无需渲染任何东西(更容易测试,更可重用等)。

缺点:

  • 没有生命周期方法。你没有办法定义componentDidMount和其他朋友。通常,您在层次结构中较高的父组件中执行此操作,因此您可以将所有子组件变成无状态的子组件。

  • 无法手动控制何时需要重新渲染,因为您无法定义shouldComponentUpdate. 每次组件接收到新的道具时都会发生重新渲染(无法进行浅比较等)。未来,React 可以自动优化无状态组件,现在有一些库可以使用。由于无状态组件只是函数,基本上是“函数记忆”的经典问题。

  • 不支持参考:https ://github.com/facebook/react/issues/4936

扩展 PureComponent 类的组件 VS 扩展 Component 类的普通组件:

React 曾经有一个PureRenderMixin你可以附加到使用React.createClass语法定义的类。mixin
将简单地定义shouldComponentUpdate在下一个 props
和下一个状态之间执行浅比较,以检查是否有任何变化。如果没有任何变化,则无需执行重新渲染。

如果要使用 ES6 语法,则不能使用 mixins。因此,为了方便起见,React
引入了一个PureComponent可以继承的类,而不是使用Component.
PureComponent只是shouldComponentUpdate以与PureRendererMixin.
这主要是一件方便的事情,因此您不必自己实现它,因为当前/下一个状态和道具之间的浅比较可能是最常见的场景,可以让您快速获得一些性能胜利。

例子:

class UserAvatar extends Component {    render() {       return <div><img src={this.props.imageUrl} /> {{ this.props.username }} </div>    }}

如您所见,输出取决于props.imageUrland props.username。如果在父组件<UserAvatarusername="fabio" imageUrl="http://foo.com/fabio.jpg" />中使用相同的 props
渲染,Reactrender每次都会调用,即使输出完全相同。请记住,尽管 React 实现了 dom diff,因此 DOM
不会实际更新。尽管如此,执行 dom 差异可能会很昂贵,因此在这种情况下,这将是一种浪费。

如果UserAvatar组件改为扩展PureComponent,则执行浅比较。并且因为 props 和 nextProps
是一样的,render根本不会被调用。

关于 React 中“纯”定义的注释:

通常,“纯函数”是在给定相同输入的情况下始终计算相同结果的函数。输出(对于
React,即render方法返回的内容)不依赖于任何历史/状态,也没有任何副作用(改变函数外部“世界”的操作)。

在 React 中,如果您将“无状态”称为从不调用this.setState且不使用this.state.

实际上,在 a 中PureComponent,您仍然可以在生命周期方法中执行副作用。例如,您可以在内部发送一个 ajax
请求,componentDidMount或者您可以执行一些 DOM 计算来动态调整render.

“哑组件”定义具有更“实用”的含义(至少在我的理解中):哑组件通过道具“被告知”父组件要做什么,并且不知道如何做事但使用道具而是回调。

“聪明”的例子AvatarComponent

class AvatarComponent extends Component {    expandAvatar () {        this.setState({ loading: true });        sendAjaxRequest(...).then(() => {            this.setState({ loading: false });        });    }    render () {        <div onClick={this.expandAvatar}>            <img src={this.props.username} />        </div>    }}

“哑巴”的例子AvatarComponent

class AvatarComponent extends Component {    render () {        <div onClick={this.props.onExpandAvatar}>            {this.props.loading && <div className="spinner" />}            <img src={this.props.username} />        </div>    }}

最后,我会说“哑”、“无状态”和“纯”是完全不同的概念,有时可能会重叠,但不一定,主要取决于您的用例。

react 如何通过 shouldComponentUpdate 来减少重复渲染

react 如何通过 shouldComponentUpdate 来减少重复渲染

OSC 请你来轰趴啦!1028 苏州源创会,一起寻宝 AI 时代

在 react 开发中,经常会遇到组件重复渲染的问题,父组件一个 state 的变化,就会导致以该组件的所有子组件都重写 render,尽管绝大多数子组件的 props 没有变化

render 什么时候会触发

首先,先上一张 react 生命周期图:

这张图将 react 的生命周期分为了三个阶段:生成期、存在期、销毁期,这样在 create、props、state、unMount 状态变化时我们可以清楚的看到 reacte 触发了哪些生命周期钩子以及什么时候会 render。

如果我们需要更改 root 的一个 state,使绿色组件视图更改

如果你写过 vue,你会发现组件更新是如上图那样的(视图指令已编译为修改视图的函数存放在绑定的 state 里的属性里,所以能够做到靶向修改),而 react 会以组件为根,重新渲染整个组件子树,如下图(绿色是期望的 render 路径,橙色是无用 render):

所以在 react 里,我们探讨的 render 性能优化是 react 调用 render 的路径如下:

如何避免这些不必要的 render:

shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState)

使用 shouldComponentUpdate () 以让 React 知道当前状态或属性的改变是否不影响组件的输出,默认返回 ture,返回 false 时不会重写 render,而且该方法并不会在初始化渲染或当使用 forceUpdate () 时被调用,我们要做的只是这样:

shouldComponentUpdate(nextProps, nextState) {
  return nextState.someData !== this.state.someData
}

但是,state 里的数据这么多,还有对象,还有复杂类型数据,react 的理念就是拆分拆分再拆分,这么多子组件,我要每个组件都去自己一个一个对比吗??不存在的,这么麻烦,要知道我们的终极目标是不劳而获 -_-

React.PureComponent

React.PureComponent 与 React.Component 几乎完全相同,但 React.PureComponent 通过 props 和 state 的浅对比来实现 shouldComponentUpate ()。如果对象包含复杂的数据结构,它可能会因深层的数据不一致而产生错误的否定判断 (表现为对象深层的数据已改变视图却没有更新)

关注点:
  • 无论组件是否是 PureComponent,如果定义了 shouldComponentUpdate (),那么会调用它并以它的执行结果来判断是否 update。在组件未定义 shouldComponentUpdate () 的情况下,会判断该组件是否是 PureComponent,如果是的话,会对新旧 props、state 进行 shallowEqual 比较,一旦新旧不一致,会触发 update。
  • 浅判等 只会比较到两个对象的 ownProperty 是否符合 Object.js() 判等,不会递归地去深层比较 --- 源码
const 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: mixed, y: mixed): boolean {
  // 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: mixed, objB: mixed): boolean {
  if (is(objA, objB)) {
    return true;
  }

  if (typeof objA !== ''object'' || objA === null ||
      typeof objB !== ''object'' || objB === null) {
    return false;
  }

  const keysA = Object.keys(objA);
  const keysB = Object.keys(objB);

  if (keysA.length !== keysB.length) {
    return false;
  }

  // Test for A''s keys different from B.
  for (let i = 0; i < keysA.length; i++) {
    if (
      !hasOwnProperty.call(objB, keysA[i]) ||
      !is(objA[keysA[i]], objB[keysA[i]])
    ) {
      return false;
    }
  }

  return true;
}
  • 至于复杂数据结构,用 Object.key () 获取下 key,然后 key 和对应的 value 都是基础类型数据,就是算是简单数据结构,不然就是复杂

针对以上规则我们在项目开发种可以做出如下优化:

尽量将复杂类型数据(ArrayList)所关联的视图单独拆成 PureComonent 有助于提高渲染性能,比如表单、文本域和复杂列表在同一个 render () 中,表单域的输入字段改变会频繁地触发 setState () 从而导致 组件 重新 render ()。而用于渲染复杂列表的数据其实并没有变化,但由于重新触发 render (),列表还是会重新渲染。

react-immutable-render-mixin

我想复杂数组没变化时也不要 render (), 那你用 react-immutable-render-mixin,来,我们看看插件的介绍:

Users are urged to use PureRenderMixin with facebook/immutable-js. If performance is still an issue an examination of your usage of Immutable.js should be your first path towards a solution. This library was created from experimentations with Immutable that were ultimately erroneous; improper usage of Immutable.js . Users should be able to achieve maximum performance simply using PureRenderMixin.


译:不能以正确的姿势来使用 immutable-js 做优化,你就不要瞎折腾了,用它 react-immutable-render-mixin 就行了

它和 ProComponent 原理一样,唯一的区别就是新旧数据的对比,react-immutable-render-mixin 用了 immutable-js 的 is () 方法去做对比,性能强,复杂类型数据也能对比(这里不对 immutable-js 做讨论,一篇很不错的文章 Immutable 详解及 React 中实践), 相比于 React.PureComponent 更方便 --- 源码

import Immutable from ''immutable'';

const is = Immutable.is.bind(Immutable);

export default function shallowEqualImmutable(objA, objB) {
  if (objA === objB || is(objA, objB)) {
    return true;
  }

  if (typeof objA !== ''object'' || objA === null ||
      typeof objB !== ''object'' || objB === null) {
    return false;
  }

  const keysA = Object.keys(objA);
  const keysB = Object.keys(objB);

  if (keysA.length !== keysB.length) {
    return false;
  }

  // Test for A''s keys different from B.
  const bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);
  for (let i = 0; i < keysA.length; i++) {
    if (!bHasOwnProperty(keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
      return false;
    }
  }

  return true;
}

用法很多,我喜欢 Decorator:

import React from ''react'';
import { immutableRenderDecorator } from ''react-immutable-render-mixin'';

@immutableRenderDecorator
class Test extends React.Component {
  render() {
    return <div></div>;
  }
}

react 常见组件问题 Can''t perform a React state update on an unmounted component

react 常见组件问题 Can''t perform a React state update on an unmounted component

在些 react 组件的时候,会有这个警告

Can''t perform a React state update on an unmounted component. 
This is a no-op, but it indicates a memory leak in your application.
 To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method”

  这是因为在写一个方法完成请求后我们改变 state 状态,

  payload:values,
        callback:res=>{
          if(res.code === 0){
            notification.success({
              message: ''密码更新成功'',
              description: `新密码为 ${res.data}`,
              duration: 0,
            });
            successed&& successed();
              that.setState({
                updatePwdModalVisible:false
              })
            that.getCaptcha();

解决方法:利用生命周期钩子函数:componentWillUnmount,在组件卸载前清除timer

that.pwdErrorTimer = setTimeout(() => {
              this.setState({
                updatePwdModalVisible:false
              })
            }, 1000);

  

componentWillUnmount(){
    clearTimeout(this.pwdErrorTimer);
  }

  

关于在没有shouldComponentUpdate的情况下,React 0.14的无状态组件将如何提高性能?的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于linux – 如何在没有Segmentation错误的情况下在Google Compute Engine上运行R.、React 函数式无状态组件,PureComponent,Component;有什么区别,我们什么时候应该使用什么?、react 如何通过 shouldComponentUpdate 来减少重复渲染、react 常见组件问题 Can''t perform a React state update on an unmounted component的相关信息,请在本站寻找。

本文标签: