博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解读React源码(三):生命周期的管理艺术
阅读量:6210 次
发布时间:2019-06-21

本文共 5412 字,大约阅读时间需要 18 分钟。

前言

React的主要思想是通过构建可复用组件来构建页面.

所谓组件,其实就是有限状态机(FSM),通过状态渲染对应的界面,且每个组件都有自己的生命周期,
它规定了组件的状态和方法需要在哪个阶段改变和执行.

class Collections extends Component {    constructor(props) {        super(props);        this.state = {            a: 1        }    }    add = () => {        this.setState({            a: this.state.a + 1        });    }    componentWillMount() {        console.log('componentWillMount');    }    componentDidMount() {        console.log('componentDidMount');        this.setState({            a: 2        });    }    componentWillUnMount() {        console.log('componentWillUnMount');    }    render() {        console.log('render');        return (            
{ this.state.a }
); }}
import React, { Component, PropTypes } from 'react';export default class Example extends Component {    static propTypes = {        a: PropTypes.number.isRequired    };    static defaultProps = {        a: 0    };     constructor(props) {        super(props);        this.state = {            b: 1        };    }    add = () => {        this.setState({            b: this.state.b + 1        });    }    componentWillReceiveProps(nextProps) {        console.log(nextProps);        if (nextProps.a === 4) {            this.setState({                b: 1000            });        }    }    shouldComponentUpdate(nextProps, nextState) {        console.log(nextProps);        console.log(nextState);        if (nextState.b === 4) {            return false;        }        return true;    }    componentWillMount() {        console.log('子组件componentWillMount');    }    componentDidMount() {        console.log('子组件componentDidMount');    }    render() {        console.log('子组件render');        return (            

a:{ this.props.a }

b:{ this.state.b }

); }}

初探react生命周期

当首次挂载组件时,按顺序执行getDefaultProps,getInitialState,componentWillMount,render,componentDidMount

当卸载组件时,执行componentWillUnMount
当再次渲染组件时,组件接收到更新状态,此时按顺序执行componentWillReceiveProps,shouldComponentUpdate,
componentWillUpdate,render和componentDidUpdate

使用createClass创建自定义组件

createClass是创建自定义组件的入口方法,负责管理生命周期方法中的getDefaultProps.

该方法在整个生命周期中只执行一次,这样所有实例初始化的props将会被共享.
通过createClass创建自定义组件,利用原型继承ReactClassComponent父类,
按顺序合并minin,设置初始化defaultProps,返回构造函数.
当使用ES6 classes编写React组件时,class MyComponent extends React.Component
其实就是调用内部方法createClass创建组件.

var ReactClass = {    // 创建自定义组件    createClass: function(spec) {        var Constructor = function(props, context, updater) {            // /自动绑定            if (this._reactAutoBindPairs.length) {                bindAutoBindMethods(this);            }            this.props = props;            this.context = context;            this.refs = emptyObject;            this.updater = updater || ReactNoopUpdateQueue;            this.state = null;            // ReactClass没有构造函数,通过getInitialState和componentWillMount来代替            var initialState = this.getInitialState ? this.getInitialState() : null;            this.state = initialState;        };        // 原型继承父类        Constructor.prototype = new ReactClassComponent();        Constructor.prototype.constructor = constructor;        Constructor.prototype._reactAutoBindPairs = [];        // 合并mixin        injectedMixins.forEach(            minSpecIntoComponent.bind(null, Constructor)        );        minSpecIntoComponent(Constructor, spec);        // 所有mixin合并后初始化defaultProps(在整个生命周期中,getDefaultProps只执行一次)        if (Constructor.getDefaultProps) {            Constructor.defaultProps = Constructor.getDefaultProps();        }        // 减少查找并设置原型的时间        for (var methodName in ReactClassInterface) {            if (!Constructor.prototype[methodName]) {                Constructor.prototype[methodName] = null;            }        }        return Constructor;    }};

MOUNTING

mountComponent负责管理生命周期中的getInitialState,componentWillMount,render和componentDidMount

由于getDefaultProps是通过构造函数进行管理的,所以也是整个生命周期中最先开始执行的.
react是利用更新队列this._pendingStateQueue以及更新状态this._pendingReplaceState
和this._pendingForceUpdate来实现setState的异步更新机制.
其实,mountComponent本质上是通过递归渲染内容的,由于递归的特性,父组件的componentWillMount
在其子组件的componentWillMount之前调用,而父组件的componentDidMount在其子组件的componentDidMount之后调用.

RECEIVE_PROPS

updateComponent负责管理生命周期中的componentWillReceiveProps,shouldComponentUpdate,componentWillUpdate,

render和componentDidUpdate.
若存在componentWillReceiveProps,则执行.
如果此时在componentWillReceiveProps中调用setState,是不会触发re-render的,而是会进行state合并.
且在componentWillReceiveProps,shouldComponentUpdate和componentWillUpdate中也还是无法获取到更新后的this.state,
即此时访问的this.state仍然是未更新的数据,因此只有render和componentDidUpdate中才能获取到更新后的this.state

componentWillReceiveProps(nextProps) {    console.log(nextProps);    if (nextProps.a === 4) {        this.setState({            b: 1000        }, () => {            console.log(this.state.b);        });    }}

UNMOUTING

unmountComponnet负责管理生命周期中的componentWillUnMount

如果存在componentWillUnMount,则执行并重置所有相关参数,更新队列以及更新状态,
如果此时在componentWillUpdate中调用setState,是不会触发re-render的,这是因为
所有更新队列和更新状态都被重置为null,并清除了公共类,完成了组件卸载操作.

无状态组件

无状态组件只是一个render方法,并没有组件类的实例化过程,也没有实例返回.

无状态组件没有状态,没有生命周期,只是简单的接受props渲染生成DOM结构,
是一个纯粹为渲染而生的组件.
由于无状态组件有简单,便捷,高效等诸多优点,所以如果可能的话请尽量使用无状态组件.

import React from 'react';const HelloWorld = (props) => {    return (        
{ props.a }
);}export default HelloWorld;

转载地址:http://eadja.baihongyu.com/

你可能感兴趣的文章
贾跃亭不是老赖?网传贾跃亭已偿还200亿债务,你怎么看? ...
查看>>
如何将本地文件上传至阿里云ECS中
查看>>
Linux性能分析和优化思维导图
查看>>
puppet实战
查看>>
初学者怎样使用Keras进行迁移学习
查看>>
干货满满:Java、前端、PHP等九大系列资料整理,全面总结,推荐收藏 ...
查看>>
python socket传文件
查看>>
“阿里云大数据技术实战训练营”江苏省大学生万人计划学术冬令营活动成功举行...
查看>>
新Kubeflow,新征程 (一):简化部署体验
查看>>
Kubernetes集群高可用的策略和实践
查看>>
Mybatis调用MySQL存储过程
查看>>
CSS(溢出_判断IE版本)
查看>>
阿里面试90%以上会问到的数据结构;HashMap
查看>>
Jdbc模板、事务管理
查看>>
hive 异常 (Attempt to do update or delete on table terminal that does not use an )
查看>>
其实,我是这么学习的
查看>>
对标华为 GPU Turbo,OPPO 推出 Hyper Boost 手机加速引擎
查看>>
行为识别论文笔记之多纤维网络 | ECCV 2018
查看>>
Java序列化 ObjectOutputStream源码解析
查看>>
web设计中那些因素可能影响网站后期优化
查看>>