ReactUpdateQueue模块,一则作为用户自定义组件ReactComponent的参数updater,供ReactComponent实例的setState、replaceState、forceUpdate方法调用ReactUpdateQueue模块的方法,用于更新state,并重绘组件;一则为用户自定义组件ReactComponent提供isMount方法判断组件是否挂载完成;一则为ReactMount模块使用,在该模块中挂载设定用户自定义组件ReactComponent元素的父节点为reactNode时,父节点更新引起的组件元素变动,将调用ReactUpdateQueue模块的方法实现组件重绘,及执行回调函数。
'use strict'; var _prodInvariant = require('./reactProdInvariant');// 生产环境React形式带url报错 // 开发环境下,ReactClass组件被实例化或其render方法被调用时,向ReactCurrentOwner.current添加ReactCompositeComponent实例 // 实例化完成或render方法执行完成,ReactCurrentOwner.current置为null var ReactCurrentOwner = require('react/lib/ReactCurrentOwner'); // 由ReactComponent实例publicInstance映射获得ReactCompositeComponent实例internalInstance var ReactInstanceMap = require('./ReactInstanceMap'); // 调试工具 var ReactInstrumentation = require('./ReactInstrumentation'); // 用于添加脏组件,并启动重绘 var ReactUpdates = require('./ReactUpdates'); // invariant(condition,format,a,b,c,d,e,f) condition为否值,替换format中的"%s",并throw error报错 var invariant = require('fbjs/lib/invariant'); // warning(condition,format) condition为否值,替换format中的"%s",并console.error警告 var warning = require('fbjs/lib/warning'); // 调用ReactUpdates.enqueueUpdate添加脏组件internalInstance,并重绘组件 function enqueueUpdate(internalInstance) { ReactUpdates.enqueueUpdate(internalInstance); } function formatUnexpectedArgument(arg) { var type = typeof arg; if (type !== 'object') { return type; } var displayName = arg.constructor && arg.constructor.name || type; var keys = Object.keys(arg); if (keys.length > 0 && keys.length < 20) { return displayName + ' (keys: ' + keys.join(', ') + ')'; } return displayName; } // 由用户自定义组件ReactComponent实例publicInstance,获取对应的ReactCompositeComponent实例 function getInternalInstanceReadyForUpdate(publicInstance, callerName) { // 由用户自定义组价ReactComponent实例publicInstance,获得react内部使用ReactCompositeComponent实例internalInstance var internalInstance = ReactInstanceMap.get(publicInstance); // 无法取得ReactCompositeComponent实例,警告 if (!internalInstance) { if (process.env.NODE_ENV !== 'production') { var ctor = publicInstance.constructor; process.env.NODE_ENV !== 'production' ? warning(!callerName, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, ctor && (ctor.displayName || ctor.name) || 'ReactClass') : void 0; } return null; } // 组件的render方法执行过程中,更新state,警告 if (process.env.NODE_ENV !== 'production') { process.env.NODE_ENV !== 'production' ? warning(ReactCurrentOwner.current == null, '%s(...): Cannot update during an existing state transition (such as ' + 'within `render` or another component\'s constructor). Render methods ' + 'should be a pure function of props and state; constructor ' + 'side-effects are an anti-pattern, but can be moved to ' + '`componentWillMount`.', callerName) : void 0; } return internalInstance; } var ReactUpdateQueue = { // 自定义组件的isMounted方法调用,判断组件元素是否渲染完成,执行render方法 isMounted: function (publicInstance) { // 用户自定义组件reactComponent实例化或执行render方法过程中,警告 if (process.env.NODE_ENV !== 'production') { var owner = ReactCurrentOwner.current; if (owner !== null) { process.env.NODE_ENV !== 'production' ? warning(owner._warnedAboutRefsInRender, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : void 0; owner._warnedAboutRefsInRender = true; } } // 获取对应的ReactCompositeComponent实例internalInstance var internalInstance = ReactInstanceMap.get(publicInstance); // 用户自定义组件reactComponent实例的render方法执行完成,internalInstance._renderedComponent为真值 if (internalInstance) { return !!internalInstance._renderedComponent; } else { return false; } }, // 由用户自定义组件的setState、replaceState、forceUpdate方法调用,重绘组件后触发回调 // 参数publicInstance为用户自定义组件ReactComponent实例 // 参数callback为回调,添加到关联的ReactCompositeComponent实例的_pendingCallbacks属性中 // 参数callerName为函数名,校验callback时报错提示需要 enqueueCallback: function (publicInstance, callback, callerName) { // 校验callback是否函数 ReactUpdateQueue.validateCallback(callback, callerName); // 获取ReactCompositeComponent实例,通过用户自定义组件实例publicInstance获得 var internalInstance = getInternalInstanceReadyForUpdate(publicInstance); if (!internalInstance) { return null; } if (internalInstance._pendingCallbacks) { internalInstance._pendingCallbacks.push(callback); } else { internalInstance._pendingCallbacks = [callback]; } // 添加脏组件internalInstance,并重绘组件 enqueueUpdate(internalInstance); }, // 由ReactMount调用,添加ReactUpdateQueue.enqueueElementInternal发起组件重绘后的回调 enqueueCallbackInternal: function (internalInstance, callback) { if (internalInstance._pendingCallbacks) { internalInstance._pendingCallbacks.push(callback); } else { internalInstance._pendingCallbacks = [callback]; } // 添加脏组件internalInstance,并重绘组件 enqueueUpdate(internalInstance); }, // 由用户自定义组件的forceUpdate方法调用,强制重绘组件 // 参数publicInstance为用户自定义组件ReactComponent实例 enqueueForceUpdate: function (publicInstance) { // 获取ReactCompositeComponent实例,通过用户自定义组件实例publicInstance获得 var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'forceUpdate'); if (!internalInstance) { return; } internalInstance._pendingForceUpdate = true; // 添加脏组件internalInstance,并重绘组件 enqueueUpdate(internalInstance); }, // 由用户自定义组件的replaceState方法调用 // 用于将更迭的state数据,推送到关联的ReactCompositeComponent实例internalInstance的_pendingStateQueue属性中 // 以及调用eactUpdates.enqueueUpdate添加脏组件internalInstance,并重绘组件 // 参数publicInstance为用户自定义组件ReactComponent实例 // 参数completeState为state的部分重设值 enqueueReplaceState: function (publicInstance, completeState) { // 获取ReactCompositeComponent实例,通过用户自定义组件实例publicInstance获得 var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'replaceState'); if (!internalInstance) { return; } // 将待更新的completeState添加到ReactCompositeComponent实例的_pendingStateQueue属性中 internalInstance._pendingStateQueue = [completeState]; internalInstance._pendingReplaceState = true; // 添加脏组件internalInstance,并重绘组件 enqueueUpdate(internalInstance); }, // 由用户自定义组件的setState方法调用 // 用于将更迭的state数据,推送到关联的ReactCompositeComponent实例internalInstance的_pendingStateQueue属性中 // 以及调用eactUpdates.enqueueUpdate添加脏组件internalInstance,并重绘组件 // 参数publicInstance为用户自定义组件ReactComponent实例 // 参数partialState为state的部分重设值 enqueueSetState: function (publicInstance, partialState) { if (process.env.NODE_ENV !== 'production') { ReactInstrumentation.debugTool.onSetState(); process.env.NODE_ENV !== 'production' ? warning(partialState != null, 'setState(...): You passed an undefined or null state object; ' + 'instead, use forceUpdate().') : void 0; } // 获取ReactCompositeComponent实例,通过用户自定义组件实例publicInstance获得 var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState'); if (!internalInstance) { return; } // 将待更新的partialState添加到ReactCompositeComponent实例的_pendingStateQueue属性中 var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []); queue.push(partialState); // 添加脏组件internalInstance,并重绘组件 enqueueUpdate(internalInstance); }, // 由ReactMount调用,通过ReactDom.render方法挂载的组件元素其父节点由react组件元素渲染,当父节点变更时,同时引起子组件元素变更 // 通过向ReactCompositeComponent实例添加_pendingElement属性的方式重绘子组件,即ReactDom.render挂载的组件元素 enqueueElementInternal: function (internalInstance, nextElement, nextContext) { internalInstance._pendingElement = nextElement; internalInstance._context = nextContext; // 添加脏组件internalInstance,并重绘组件 enqueueUpdate(internalInstance); }, // 校验setState、replaceState、forceUpdate后执行的callback是否函数 validateCallback: function (callback, callerName) { !(!callback || typeof callback === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s(...): Expected the last optional `callback` argument to be a function.' + ' Instead received: %s.', callerName, formatUnexpectedArgument(callback)) : _prodInvariant('122', callerName, formatUnexpectedArgument(callback)) : void 0; } }; // ReactUpdateQueue将作为参数updater传入自定义组件,组件setState、replaceState、forceUpdate能调用ReactUpdateQueue诸方法 module.exports = ReactUpdateQueue;