We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mountComponent: function( transaction, hostParent, hostContainerInfo, context, ) { this._context = context; this._mountOrder = nextMountID++;//模块全局属性nextMountID,赋值给实例的私有属性。 this._hostParent = hostParent; this._hostContainerInfo = hostContainerInfo; var publicProps = this._currentElement.props;//这里的_currentElement指的TopLevelWrapper 类型的元素,它的props中的child属性对象的是真正的元素,详见[React源码学习-新建一个组件](https://github.com/hitobear/blog/issues/9) var publicContext = this._processContext(context); var Component = this._currentElement.type; var updateQueue = transaction.getUpdateQueue(); // Initialize the public class var doConstruct = shouldConstruct(Component); var updateQueue = transaction.getUpdateQueue();//作为参数传给实例构造使用,什么用? var inst = this._constructComponent( doConstruct, publicProps, publicContext, updateQueue, ); var renderedElement; // Support functional components if (!doConstruct && (inst == null || inst.render == null)) { renderedElement = inst; ...... } this._instance = inst;//将真正的组件实例赋值给私有变量_instance // Store a reference from the instance back to the internal representation ReactInstanceMap.set(inst, this);将组件实例对象和这个包裹对象(ReactCompositeComponent类型的对象)作为key,value存入map var initialState = inst.state; if (initialState === undefined) {//什么时候不等于undefiend,构造函数中的setState会已经生效了?? inst.state = initialState = null; } var markup; if (inst.unstable_handleError) { markup = this.performInitialMountWithErrorHandling( renderedElement, hostParent, hostContainerInfo, transaction, context, ); } else { markup = this.performInitialMount(//执行componentWillMount方法,递归挂载子节点元素 renderedElement, hostParent, hostContainerInfo, transaction, context, ); } ... if (inst.componentDidMount) { if (__DEV__) { ...... }); } else { transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);//执行 //componentDidMount的方法,这里transaction.getReactMountReady是什么? //enqueue又有什么用?应该是所有子孙的componentDidMount都会在所有组件挂载完后 //依入栈顺序来执行?mountReady就是准备完成挂载? } }
this.this._constructComponent调用的实际是this._constructComponentWithoutOwner,在这个方法中,终于真正的调用了自定义组件的构造函数生成了组件类的一个实例对象,关键代码如下:
var Component = this._currentElement.type;(//this._currentElement.type就是自定义的组件函数) if (doConstruct) { return new Component(publicProps, publicContext, updateQueue); } else{ return Component(publicProps, publicContext, updateQueue); }
核心逻辑代码如下
performInitialMount: function( renderedElement, hostParent, hostContainerInfo, transaction, context, ) { var inst = this._instance; if (inst.componentWillMount) { ...... inst.componentWillMount(); ...... // When mounting, calls to `setState` by `componentWillMount` will set // `this._pendingStateQueue` without triggering a re-render. componentWillMount中的setState不会 //触发组件重绘,而是设置_pendingStateQuque变量,设置了之后什么时候生效,render方法的时候就会生效了把? if (this._pendingStateQueue) { inst.state = this._processPendingState(inst.props, inst.context); } } // If not a stateless component, we now rende如果是一个无状态函数组件,renderedElement已经 //有值了,回退查代码 if (renderedElement === undefined) { renderedElement = this._renderValidatedComponent();//执行组件的render()方法,生成的是一个元素对象,和开始ReactDom.render(element,ddd)中的第一个元素是同类 } var nodeType = ReactNodeTypes.getType(renderedElement); this._renderedNodeType = nodeType; var child = this._instantiateReactComponent( renderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */, ); //这里this_instantiateReactComponent方法和ReactMount中的instantiateReactComponent方法是同一个,是ReactCompositeComponent的原型被赋值过,详见[新建一个组件-instantiateReactComponent()方法](https://github.com/hitobear/blog/issues/9) this._renderedComponent = child; //调用instantiate方法后,把下一级元素对象转化成了ReactCompositeComponentWrapper类的对象,和当前对像是同类,进而递归,调用 ReactReconciler.mountComponent(当初第一个渲染的元素的mountComponent方法就是通过这里一步步入栈过来的),其中代代子孙共享的是同一个transatcion变量(这也是为什么transaction要从外层传了?因为从ReactReconciler.mountComponent开始调,所以为了共享一个transaction,必须要在这之前就得到transaction) var markup = ReactReconciler.mountComponent( child, transaction, hostParent, hostContainerInfo, this._processChildContext(context), debugID, ); return markup;
看上去递归没有尽头,实际上我们只分析了自定义组件的渲染过程,知道string类型的元素(底层dom)为止,递归应该会结束。
源码
_processPendingState: function(props, context) { var inst = this._instance; var queue = this._pendingStateQueue;//待合并的状态 var replace = this._pendingReplaceState;//替换状态标志,真表示激活,对原状态进行替换, //假表示未激活,进行状态合并 this._pendingReplaceState = false;//默认情况下,没有激活替换状态 this._pendingStateQueue = null; if (!queue) {//队列里没有值,说明没有待合并的,则直接返回原状态即可 return inst.state; } if (replace && queue.length === 1) { return queue[0];//替换标记激活,且队列里只有一个值的话,无需合并,直接返回新值即可 } var nextState = Object.assign({}, replace ? queue[0] : inst.state);//剩下的情况,根据replace标记而定 //初始值,要么是原状态值`inst.state`,要么是queue[0], for (var i = replace ? 1 : 0; i < queue.length; i++) { var partial = queue[i]; Object.assign( nextState, typeof partial === 'function' ? partial.call(inst, nextState, props, context) : partial, ); } return nextState; },
The text was updated successfully, but these errors were encountered:
No branches or pull requests
mountComponent方法
this._constructComponent->this._constructComponentWithoutOwner
this.this._constructComponent调用的实际是this._constructComponentWithoutOwner,在这个方法中,终于真正的调用了自定义组件的构造函数生成了组件类的一个实例对象,关键代码如下:
this.performInitialMount
核心逻辑代码如下
看上去递归没有尽头,实际上我们只分析了自定义组件的渲染过程,知道string类型的元素(底层dom)为止,递归应该会结束。
this._processPendingState
源码
疑问
The text was updated successfully, but these errors were encountered: