内容简介:1.所谓而本来我们做的事情如下,这里判断了2.上面提到的某些情况下可以使用
1.所谓 浅比较
(shallowEqual),即react源码中的一个函数,然后根据下面的方法进行是不是 PureComponent
的判断,帮我们做了本来应该我们在 shouldComponentUpdate
中做的事情
if (this._compositeType === CompositeTypes.PureClass) { shouldUpdate = !shallowEqual(prevProps, nextProps) || ! shallowEqual(inst.state, nextState); } 复制代码
而本来我们做的事情如下,这里判断了 state
有没有发生变化(prop同理),从而决定要不要重新渲染,这里的函数在一个继承了 Component
的组件中,而这里 this.state.person
是一个对象,你会发现,
在这个对象的引用没有发生变化的时候是不会重新 render
的(即下面提到的第三点),所以我们可以用 shouldComponentUpdate
进行优化,这个方法如果返回 false
,表示不需要重新进行渲染,返回 true
则重新渲染,默认返回 true
shouldComponentUpdate(nextProps, nextState) { return (nextState.person !== this.state.person); } 复制代码
2.上面提到的某些情况下可以使用 PureComponent
来提升性能,那具体是哪些情况可以,哪些情况不可以呢,实践出真知
3.如下显示的是一个 IndexPage
组件,设置了一个 state
是 isShow
,通过一个按钮点击可以改变它的值,结果是:初始化的时候输出的是 constructor
, render
,
而第一次点击按钮,会输出一次render,即重新渲染了一次,界面也会从显示 false
变成显示 true
,但是当这个组件是继承自 PureComponent
的时候,再点击的时,不会再输出 render
,即不会再重新渲染了,
而当这个组件是继承自 Component
时,还是会输出 render
,还是会重新渲染,这时候就是 PureComponent
内部做了优化的体现
4.同理也适用于 string
, number
等基本数据类型,因为基本数据类型,值改变了就算改变了
import React, { PureComponent } from 'react'; class IndexPage extends PureComponent{ constructor() { super(); this.state = { isShow: false }; console.log('constructor'); } changeState = () => { this.setState({ isShow: true }) }; render() { console.log('render'); return ( <div> <button onClick={this.changeState}>点击</button> <div>{this.state.isShow.toString()}</div> </div> ); } } 复制代码
5.当这个 this.state.arr
是一个数组时,且这个组件是继承自 PureComponent
时,初始化依旧是输出 constructor
和 render
,但是当点击按钮时,界面上没有变化,也没有输出 render
,证明没有渲染,但是我们可以从下面的注释中看到,每点击
一次按钮,我们想要修改的 arr
的值已经改变,而这个值将去修改 this.state.arr
,但是因为在 PureComponent
中 浅比较
这个数组的引用没有变化所以没有渲染, this.state.arr
也没有更新,因为在 this.setState()
以后,值是在 render
的时候更新的,
这里涉及到 this.setState()
的知识
6.但是当这个组件是继承自 Component
的时候,初始化依旧是输出 constructor
和 render
,但是当点击按钮时,界面上出现了变化,即我们打印处理的 arr
的值输出,而且每点击一次按钮都会输出一次 render
,证明已经重新渲染, this.state.arr
的值已经更新,所以
我们能在界面上看到这个变化
import React, { PureComponent } from 'react'; class IndexPage extends PureComponent{ constructor() { super(); this.state = { arr:['1'] }; console.log('constructor'); } changeState = () => { let { arr } = this.state; arr.push('2'); console.log(arr); // ["1", "2"] // ["1", "2", "2"] // ["1", "2", "2", "2"] // .... this.setState({ arr }) }; render() { console.log('render'); return ( <div> <button onClick={this.changeState}>点击</button> <div> {this.state.arr.map((item) => { return item; })} </div> </div> ); } } 复制代码
7.下面的例子用 扩展运算符
产生新数组,使 this.state.arr
的引用发生了变化,所以初始化的时候输出 constructor
和 render
后,每次点击按钮都会输出 render
,界面也会变化,不管该组件是继承自 Component
还是 PureComponent
的
import React, { PureComponent } from 'react'; class IndexPage extends PureComponent{ constructor() { super(); this.state = { arr:['1'] }; console.log('constructor'); } changeState = () => { let { arr } = this.state; this.setState({ arr: [...arr, '2'] }) }; render() { console.log('render'); return ( <div> <button onClick={this.changeState}>点击</button> <div> {this.state.arr.map((item) => { return item; })} </div> </div> ); } } 复制代码
8.上面的情况同样适用于 对象
的情况
二.PureComponent不仅会影响本身,而且会影响子组件,所以PureComponent最佳情况是展示组件
1.我们让 IndexPage
组件里面包含一个子组件 Example
来展示 PureComponent
是如何影响子组件的
2.父组件继承 PureComponent
,子组件继承 Component
时:下面的结果初始化时输出为 constructor
, IndexPage render
, example render
,但是当我们点击按钮时,界面没有变化,因为这个 this.state.person
对象的引用没有改变,只是改变了它里面的属性值
所以尽管子组件是继承 Component
的也没有办法渲染,因为父组件是 PureComponent
,父组件根本没有渲染,所以子组件也不会渲染
3.父组件继承 PureComponent
,子组件继承 PureComponent
时:因为渲染在父组件的时候就没有进行,相当于被拦截了,所以子组件是 PureComponent
还是 Component
根本不会影响结果,界面依旧没有变化
4.父组件继承 Component
,子组件继承 PureComponent
时:结果和我们预期的一样,即初始化是会输出 constructor
, IndexPage render
, example render
,但是点击的时候只会出现 IndexPage render
,因为父组件是 Component
,所以父组件会渲染,但是
当父组件把值传给子组件的时候,因为子组件是 PureComponent
,所以它会对 prop
进行浅比较,发现这个 person
对象的引用没有发生变化,所以不会重新渲染,而界面显示是由子组件显示的,所以界面也不会变化
5.父组件继承 Component
,子组件继承 Component
时:初始化是会输出 constructor
, IndexPage render
, example render
,当我们第一次点击按钮以后,界面发生变化,后面就不再改变,因为我们一直把它设置为sxt2,但是每点击一次
都会输出 IndexPage render
, example render
,因为
每次不管父组件还是子组件都会渲染
6.所以正如下面第四条说的,如果 state
和 prop
一直变化的话,还是建议使用 Component
,并且 PureComponent
的最好作为展示组件
//父组件 import React, { PureComponent, Component } from 'react'; import Example from "../components/Example"; class IndexPage extends PureComponent{ constructor() { super(); this.state = { person: { name: 'sxt' } }; console.log('constructor'); } changeState = () => { let { person } = this.state; person.name = 'sxt2'; this.setState({ person }) }; render() { console.log('IndexPage render'); const { person } = this.state; return ( <div> <button onClick={this.changeState}>点击</button> <Example person={person} /> </div> ); } } //子组件 import React, { Component } from 'react'; class Example extends Component { render() { console.log('example render'); const { person } = this.props; return( <div> {person.name} </div> ); } } 复制代码
三.若是数组和对象等引用类型,则要引用不同,才会渲染
四.如果prop和state每次都会变,那么PureComponent的效率还不如Component,因为你知道的,进行浅比较也是需要时间
五.若有shouldComponentUpdate,则执行它,若没有这个方法会判断是不是PureComponent,若是,进行浅比较
1.继承自 Component
的组件,若是 shouldComponentUpdate
返回 false
,就不会渲染了,继承自 PureComponent
的组件不用我们手动去判断 prop
和 state
,所以在 PureComponent
中使用 shouldComponentUpdate
会有如下警告:
IndexPage has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.
也是比较好理解的,就是不要在 PureComponent
中使用 shouldComponentUpdate
,因为根本没有必要
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
High Performance Python
Andrew Lewis / O'Reilly Media, Inc. / 2010-09-15 / USD 34.99
Chapter 1. Introduction Section 1.1. The High Performance Buzz-word Chapter 2. The Theory of Computation Section 2.1. Introduction Section 2.2. Problems Section 2.3. Models of Computati......一起来看看 《High Performance Python》 这本书的介绍吧!
JSON 在线解析
在线 JSON 格式化工具
Markdown 在线编辑器
Markdown 在线编辑器