一、物料准备
1.克隆react源码, github 地址:https://github.com/facebook/react.git
2.安装gulp
3.在react源码根目录下:
$npm install
$gulp default
(建议使用node 6.0+)
gulp将文件处理在根目录下的build文件夹中,打开build查看react的源码,结构清晰,引用路径明了
二、从生成 virtual dom 开始
react 生成一个组件有多种写法:
es 5下:var Cp=React.createClass({...})
es 6下:class Cp extends React.Component{...}
下面打开./build/node_modules/react/lib 文件夹,找到React.js 可以看到如下关键代码:
var React = { // Modern Children: { map: ReactChildren.map, forEach: ReactChildren.forEach, count: ReactChildren.count, toArray: ReactChildren.toArray, only: onlyChild }, Component: ReactComponent, PureComponent: ReactPureComponent, createElement: createElement, cloneElement: cloneElement, isValidElement: ReactElement.isValidElement, // Classic PropTypes: ReactPropTypes, createClass: ReactClass.createClass, createFactory: createFactory, createMixin: function (mixin) { // Currently a noop. Will be used to validate and trace mixins. return mixin; }, // This looks DOM specific but these are actually isomorphic helpers // since they are just generating DOM strings. DOM: ReactDOMFactories, version: ReactVersion, // Deprecated hook for JSX spread, don't use this for anything. __spread: __spread };
由此得知:React.createClass => ReactClass.createClass
React.component => ReactComponent
1.ReactClass.createClass
下面还是在当前的目录下寻找ReactClass.js文件,查看到如下关键代码段:
var ReactClass = { createClass: function (spec) { var Constructor = function (props, context, updater) { //如果不是生产环境 输出信息类警告 目前忽略 if (process.env.NODE_ENV !== 'production') {...} // 自动绑定相关方法 目前忽略 if (this.__reactAutoBindPairs.length) {...} //为组件绑定props context refs updater属性 this.props = props; this.context = context; this.refs = emptyObject; this.updater = updater || ReactNoopUpdateQueue; //初始组件state为null this.state = null; //如果有getInitialState则执行 var initialState = this.getInitialState ? this.getInitialState() : null; //在非生产环境下为配合mock 设置initialState为null 目前忽略 if (process.env.NODE_ENV !== 'production') {...} //其他情况下的兼容性处理,目前忽略 ... //将初始化的state赋值给组件state this.state = initialState; }; //设置Constructor的原型 Constructor.prototype = new ReactClassComponent(); Constructor.prototype.constructor = Constructor; Constructor.prototype.__reactAutoBindPairs = []; //合并研发同学写入的createClass({中的东西}) mixSpecIntoComponent(Constructor, spec); //如果存在getDefaultProps则执行 if (Constructor.getDefaultProps) { Constructor.defaultProps = Constructor.getDefaultProps(); } ...省略一些无关主逻辑的操作 return Constructor; } };