网站关键词排名全掉了,网页设计技术论文范文,json api wordpress,学编程在哪里学比较正规对一个框架源码的解读#xff0c;既有利于更深入地了解框架#xff0c;使用上更得心应手#xff0c;又可以学习到其中代码组织的思路#xff0c;吸收其精华简洁的写法以便于日常工作上使用。下面我就挑选近年大热门react#xff08;15.3.1#xff09;#xff0c;从中剖析… 对一个框架源码的解读既有利于更深入地了解框架使用上更得心应手又可以学习到其中代码组织的思路吸收其精华简洁的写法以便于日常工作上使用。下面我就挑选近年大热门react15.3.1从中剖析框架的设计思路由浅入深地学习。 我们从这个文件开始看起这是react的主入口./lib/react.js。 /*** Copyright 2013-present, Facebook, Inc.* All rights reserved.** This source code is licensed under the BSD-style license found in the* LICENSE file in the root directory of this source tree. An additional grant* of patent rights can be found in the PATENTS file in the same directory.** providesModule React*/use strict;var _assign require(object-assign);var ReactChildren require(./ReactChildren);
var ReactComponent require(./ReactComponent);
var ReactPureComponent require(./ReactPureComponent);
var ReactClass require(./ReactClass);
var ReactDOMFactories require(./ReactDOMFactories);
var ReactElement require(./ReactElement);
var ReactPropTypes require(./ReactPropTypes);
var ReactVersion require(./ReactVersion);var onlyChild require(./onlyChild);
var warning require(fbjs/lib/warning);var createElement ReactElement.createElement;
var createFactory ReactElement.createFactory;
var cloneElement ReactElement.cloneElement;if (process.env.NODE_ENV ! production) {var ReactElementValidator require(./ReactElementValidator);createElement ReactElementValidator.createElement;createFactory ReactElementValidator.createFactory;cloneElement ReactElementValidator.cloneElement;
}var __spread _assign;if (process.env.NODE_ENV ! production) {var warned false;__spread function () {process.env.NODE_ENV ! production ? warning(warned, React.__spread is deprecated and should not be used. Use Object.assign directly or another helper function with similar semantics. You may be seeing this warning due to your compiler. See https://fb.me/react-spread-deprecation for more details.) : void 0;warned true;return _assign.apply(null, arguments);};
}var React {// ModernChildren: {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,// ClassicPropTypes: 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, dont use this for anything.__spread: __spread
};module.exports React; 我们直接跳过前面的环境判断以及模块引入可以看到从50行起就是React的关键代码。并且我们可以清晰的从上面看到React所提供的方法。这是离我们使用者最近的一层看到信息量不多。我们就按照开发的思路一步一步地深入源码。编写一个组件当然是从创建开始我们使用的是 React.createClass不难发现React.createClass实际上引用的是ReactClass.createClass。当然我们也可以用ES6的写法直接继承至React.Component.这两种写法有什么差异存在我们先把悬念放在后面。先从createClass的源码看起./lib/ReactClass。 var ReactClass {/*** Creates a composite component class given a class specification.* See https://facebook.github.io/react/docs/top-level-api.html#react.createclass** param {object} spec Class specification (which must define render).* return {function} Component constructor function.* public*/createClass: function (spec) {var Constructor function (props, context, updater) {// This constructor gets overridden by mocks. The argument is used// by mocks to assert on what gets mounted.if (process.env.NODE_ENV ! production) {process.env.NODE_ENV ! production ? warning(this instanceof Constructor, Something is calling a React component directly. Use a factory or JSX instead. See: https://fb.me/react-legacyfactory) : void 0;}// Wire up auto-bindingif (this.__reactAutoBindPairs.length) {bindAutoBindMethods(this);}this.props props;this.context context;this.refs emptyObject;this.updater updater || ReactNoopUpdateQueue;this.state null;// ReactClasses doesnt have constructors. Instead, they use the// getInitialState and componentWillMount methods for initialization.var initialState this.getInitialState ? this.getInitialState() : null;if (process.env.NODE_ENV ! production) {// We allow auto-mocks to proceed as if theyre returning null.if (initialState undefined this.getInitialState._isMockFunction) {// This is probably bad practice. Consider warning here and// deprecating this convenience.initialState null;}}!(typeof initialState object !Array.isArray(initialState)) ? process.env.NODE_ENV ! production ? invariant(false, %s.getInitialState(): must return an object or null, Constructor.displayName || ReactCompositeComponent) : _prodInvariant(82, Constructor.displayName || ReactCompositeComponent) : void 0;this.state initialState;};Constructor.prototype new ReactClassComponent();Constructor.prototype.constructor Constructor;Constructor.prototype.__reactAutoBindPairs [];injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor));mixSpecIntoComponent(Constructor, spec);// Initialize the defaultProps property after all mixins have been merged.if (Constructor.getDefaultProps) {Constructor.defaultProps Constructor.getDefaultProps();}if (process.env.NODE_ENV ! production) {// This is a tag to indicate that the use of these method names is ok,// since its used with createClass. If its not, then its likely a// mistake so well warn you to use the static property, property// initializer or constructor respectively.if (Constructor.getDefaultProps) {Constructor.getDefaultProps.isReactClassApproved {};}if (Constructor.prototype.getInitialState) {Constructor.prototype.getInitialState.isReactClassApproved {};}}!Constructor.prototype.render ? process.env.NODE_ENV ! production ? invariant(false, createClass(...): Class specification must implement a render method.) : _prodInvariant(83) : void 0;if (process.env.NODE_ENV ! production) {process.env.NODE_ENV ! production ? warning(!Constructor.prototype.componentShouldUpdate, %s has a method called componentShouldUpdate(). Did you mean shouldComponentUpdate()? The name is phrased as a question because the function is expected to return a value., spec.displayName || A component) : void 0;process.env.NODE_ENV ! production ? warning(!Constructor.prototype.componentWillRecieveProps, %s has a method called componentWillRecieveProps(). Did you mean componentWillReceiveProps()?, spec.displayName || A component) : void 0;}// Reduce time spent doing lookups by setting these on the prototype.for (var methodName in ReactClassInterface) {if (!Constructor.prototype[methodName]) {Constructor.prototype[methodName] null;}}return Constructor;},injection: {injectMixin: function (mixin) {injectedMixins.push(mixin);}}}; 644行起createClass方法首先定义了一个Constructor构造函数折叠内部我们看看这个方法在返回一个构造函数前做了什么直接跳到681行构造函数的prototype指向一个ReactClassComponent的实例。 Constructor.prototype new ReactClassComponent(); 往上翻我们可以发现ReactClassComponent的prototype属性拷贝了ReactComponent.prototype 和 ReactClassMixin因此我们的组件可以使用ReactComponent原型上的方法。 var ReactClassComponent function () {};
_assign(ReactClassComponent.prototype, ReactComponent.prototype, ReactClassMixin); 683行到687行。定义了 __reactAutoBindPairs 为一个空数组。 先将mixin里面的方法按照keyfunction内容的顺序成对存入 __reactAutoBindPairs ,接着就是spec对象里的方法用同样的方式存入。 Constructor.prototype.__reactAutoBindPairs [];injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor));mixSpecIntoComponent(Constructor, spec); 690行我们可以看到Constructor.defaultProps 就是我们开发中 getDefaultProps()所返回的对象。 if (Constructor.getDefaultProps) {Constructor.defaultProps Constructor.getDefaultProps();} 694行 -- 712行 是在开发环境中对开发者的建议以及规范使用的警示。715行 -- 719行 可以知道我们创建一个组件需要定义的方法都在ReactClassInterface上有当前未定义的方法设置为空我们就可以通过打印组件的prototype属性清楚地在日志上知道我们有哪些api是未定义的。通过设置未定义的属性为空可以减少程序查找的时间。721行 最终返回了这个封装好的构造函数。 for (var methodName in ReactClassInterface) {if (!Constructor.prototype[methodName]) {Constructor.prototype[methodName] null;}}return Constructor; 看到这里我们可以明白一点组件实质上是一个构造函数而我们自定义的方法既存在了prototype里也按照[key,content,key,content...]的方式归纳到了Constructor.prototype.__reactAutoBindPairs 里。这是为了组件实例化时可以将这些方法直接遍历绑定在实例上并且避免了React官方指定的方法也被绑定在实例上。 接下来我们展开645行的Constructor可以看到实例化的时候主要做了两件事。654行第一件事就是将上文提到的存在Constructor.prototype.__reactAutoBindPairs 的内容成对取出绑定在实例上。 if (this.__reactAutoBindPairs.length) {bindAutoBindMethods(this);} 668行 ——679行第二件事就是判断组件是否有定义getInitialState如果有则将state设置为该方法返回的值如果没有设置state为null。 var initialState this.getInitialState ? this.getInitialState() : null;if (process.env.NODE_ENV ! production) {// We allow auto-mocks to proceed as if theyre returning null.if (initialState undefined this.getInitialState._isMockFunction) {// This is probably bad practice. Consider warning here and// deprecating this convenience.initialState null;}}!(typeof initialState object !Array.isArray(initialState)) ? process.env.NODE_ENV ! production ? invariant(false, %s.getInitialState(): must return an object or null, Constructor.displayName || ReactCompositeComponent) : _prodInvariant(82, Constructor.displayName || ReactCompositeComponent) : void 0;this.state initialState; 到这里我们大概地知道了一个组件从创建构造函数到实例化的时候做了什么事情了。后续我们继续解读更底层的ReactComponent。 希望能对大家有帮助。如果有错误的地方恳请各位大神指正。