React的主要思想是经过构建可复用组件来构建页面.
所谓组件,其实就是有限状态机(FSM),经过状态渲染对应的界面,且每一个组件都有本身的生命周期,
它规定了组件的状态和方法须要在哪一个阶段改变和执行.react
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 ( <div className="collections"> { this.state.a } <Example a={ this.state.a } /> <button onClick={ this.add }>btn</button> </div> ); } }
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 ( <div> <p>a:{ this.props.a }</p> <p>b:{ this.state.b }</p> <button onClick={ this.add }>子组件add</button> </div> ); } }
当首次挂载组件时,按顺序执行getDefaultProps,getInitialState,componentWillMount,render,componentDidMount
当卸载组件时,执行componentWillUnMount
当再次渲染组件时,组件接收到更新状态,此时按顺序执行componentWillReceiveProps,shouldComponentUpdate,
componentWillUpdate,render和componentDidUpdate异步
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; } };
mountComponent负责管理生命周期中的getInitialState,componentWillMount,render和componentDidMount
因为getDefaultProps是经过构造函数进行管理的,因此也是整个生命周期中最早开始执行的.
react是利用更新队列this._pendingStateQueue以及更新状态this._pendingReplaceState
和this._pendingForceUpdate来实现setState的异步更新机制.
其实,mountComponent本质上是经过递归渲染内容的,因为递归的特性,父组件的componentWillMount
在其子组件的componentWillMount以前调用,而父组件的componentDidMount在其子组件的componentDidMount以后调用.oop
updateComponent负责管理生命周期中的componentWillReceiveProps,shouldComponentUpdate,componentWillUpdate,
render和componentDidUpdate.
若存在componentWillReceiveProps,则执行.
若是此时在componentWillReceiveProps中调用setState,是不会触发re-render的,而是会进行state合并.
且在componentWillReceiveProps,shouldComponentUpdate和componentWillUpdate中也仍是没法获取到更新后的this.state,
即此时访问的this.state仍然是未更新的数据,所以只有render和componentDidUpdate中才能获取到更新后的this.stateui
componentWillReceiveProps(nextProps) { console.log(nextProps); if (nextProps.a === 4) { this.setState({ b: 1000 }, () => { console.log(this.state.b); }); } }
unmountComponnet负责管理生命周期中的componentWillUnMount
若是存在componentWillUnMount,则执行并重置全部相关参数,更新队列以及更新状态,
若是此时在componentWillUpdate中调用setState,是不会触发re-render的,这是由于
全部更新队列和更新状态都被重置为null,并清除了公共类,完成了组件卸载操做.this
无状态组件只是一个render方法,并无组件类的实例化过程,也没有实例返回.
无状态组件没有状态,没有生命周期,只是简单的接受props渲染生成DOM结构,
是一个纯粹为渲染而生的组件.
因为无状态组件有简单,便捷,高效等诸多优势,因此若是可能的话请尽可能使用无状态组件.prototype
import React from 'react'; const HelloWorld = (props) => { return ( <div>{ props.a }</div> ); } export default HelloWorld;