• 更新阶段的生命周期


    更新阶段的生命周期

    • componentWillReceiveProps(object nextProps) :当挂载的组件接收到新的props时被调用。此方法应该被用于比较this.props 和 nextProps以用于使用this.setState()执行状态转换。(组件内部数据有变化,使用state,但是在更新阶段又要在props改变的时候改变state,则在这个生命周期里面)

    • shouldComponentUpdate(object nextProps, object nextState) : -boolean 当组件决定任何改变是否要更新到DOM时被调用。作为一个 优化 实现比较this.props 和 nextProps 、this.state 和 nextState ,如果React应该跳过更新,返回false。

    • componentWillUpdate(object nextProps, object nextState) :在更新发生前被立即调用。你不能在此调用 this.setState() 。

    • componentDidUpdate(object prevProps, object prevState) : 在更新发生后被立即调用。(可以在DOM更新完之后,做一些收尾的工作)

    Tips:

    • React的优化是基于 shouldComponentUpdate 的,该生命周期默认返回true,所以一旦prop或state有任何变化,都会引起重新render。

    shouldComponentUpdate

    react在每个组件生命周期更新的时候都会调用一个shouldComponentUpdate(nextProps, nextState)函数。它的职责就是返回true或false,true表示需要更新,false表示不需要,默认返回为true,即便你没有显示地定义 shouldComponentUpdate 函数。这就不难解释上面发生的资源浪费了。

    为了进一步说明问题,我们再引用一张官网的图来解释,如下图( SCU表示shouldComponentUpdate,绿色表示返回true(需要更新),红色表示返回false(不需要更新);vDOMEq表示虚拟DOM比对,绿色表示一致(不需要更新),红色表示发生改变(需要更新)):

    根据渲染流程,首先会判断shouldComponentUpdate(SCU)是否需要更新。如果需要更新,则调用组件的render生成新的虚拟DOM,然后再与旧的虚拟DOM对比(vDOMEq),如果对比一致就不更新,如果对比不同,则根据最小粒度改变去更新DOM;如果SCU不需要更新,则直接保持不变,同时其子元素也保持不变。

    • C1根节点,绿色SCU (true),表示需要更新,然后vDOMEq红色,表示虚拟DOM不一致,需要更新。

    • C2节点,红色SCU (false),表示不需要更新,所以C4,C5均不再进行检查

    • C3节点同C1,需要更新

    • C6节点,绿色SCU (true),表示需要更新,然后vDOMEq红色,表示虚拟DOM不一致,更新DOM。

    • C7节点同C2

    • C8节点,绿色SCU (true),表示需要更新,然后vDOMEq绿色,表示虚拟DOM一致,不更新DOM。

    带坑的写法:

    • {...this.props} (不要滥用,请只传递component需要的props,传得太多,或者层次传得太深,都会加重shouldComponentUpdate里面的数据比较负担,因此,也请慎用spread attributes(<Component {...props} />))。

    • ::this.handleChange()。(请将方法的bind一律置于constructor)

    • this.handleChange.bind(this,id)

    • 复杂的页面不要在一个组件里面写完。

    • 请尽量使用const element。

    • map里面添加key,并且key不要使用index(可变的)。具体可参考 使用Perf工具研究React Key对渲染的影响

    • 尽量少用setTimeOut或不可控的refs、DOM操作。

    • 数据尽可能简单明了,扁平化。

    为什么要bind:

    这是因为ES6写法,也就是类(Class)的写法,React默认不会自动绑定类中的方法造成的。
    React对ES5的语法是默认有自动绑定,所以不需要加这个。
    而且,自动绑不绑定也是React决定要不要的from:https://segmentfault.com/q/1010000007247736/a-1020000007247989

    不论你用不用immutable,只要你想达到pure render,下面值得你注意!!!
    一天我和往常一样,开开心心得写着react,用着@pureRender,

    export default class  extends Component {
    ...
      render() {
        const {name,age} =this.state;
        return (
          <div>
            <Person name={name} age={age} onClick={this._handleClick.bind(this)}></Person>//bug 所在
          </div>
        )
      }
    ...
    }

    发现一个问题,对于Person这个子组件来说,在父组件re-render的时候,即使Person得前后两个props都没改变,它依旧会re-render。。即使用immutable.js也不好使。。。
    原来啊,父组件每次render,_handleClick都会执行bind(this) 这样_handleClick的引用每次都会改。。所以Person前后两次props其实是不一样的。。
    那怎么办?把bind(this)去掉?不行 还必须得用
    真正的答案是 让父组件每次render 不执行bind(this),直接提前在定义class里面的constructor执行好

    export default class  extends Component {
      constructor(props){
        super(props)
        this._handleClick=this._handleClick.bind(this)//改成这样
      }
      render() {
        const {name,age} =this.state;
        return (
          <div>
            <Person name={name} age={age} onClick={this._handleClick}></Person>
          </div>
        )
      }
    ...
    }
  • 相关阅读:
    Android WebView 获取网页的标题
    Android APK 文件自动安装
    DownloadManager 的使用
    Android Java 自定义异常
    Android NDK
    android assets文件夹资源的访问
    GitHub 基本常用知识解答2
    hbuilder egit插件的安装使用--项目文件丢失的教训
    微软收购跨平台移动应用开发商Xamarin
    Android Study 之 初识ButterKnife(8.5.1)及简单运用
  • 原文地址:https://www.cnblogs.com/little-ab/p/6971238.html
Copyright © 2020-2023  润新知