ReactChildReconciler模块用于挂载、卸载、或更新ReactDomComponent子组件。
'use strict';
var ReactReconciler = require('./ReactReconciler');
// 用于获取ReactCompositeComponent组件实例或ReactDomComponent组件实例
var instantiateReactComponent = require('./instantiateReactComponent');
// react组件的key值转译
var KeyEscapeUtils = require('./KeyEscapeUtils');
// 由组件的构造函数及key键是否相同,判断是否可以更新组件
var shouldUpdateReactComponent = require('./shouldUpdateReactComponent');
// 用于遍历props.children,触发执行instantiateChild函数,以对象形式获取相关ReactDomComponent组件实例
var traverseAllChildren = require('./traverseAllChildren');
var warning = require('fbjs/lib/warning');
var ReactComponentTreeHook;
if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'test') {
ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook');
}
// 以集合childInstances获取react组件实例
function instantiateChild(childInstances, child, name, selfDebugID) {
var keyUnique = childInstances[name] === undefined;
if (process.env.NODE_ENV !== 'production') {
if (!ReactComponentTreeHook) {
ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook');
}
if (!keyUnique) {
// ReactComponentTreeHook.getStackAddendumByID当key值相同,获取祖先节点的信息,警告用
process.env.NODE_ENV !== 'production' ?
warning(false, 'flattenChildren(...): Encountered two children with the same key, '
+ '`%s`. Child keys must be unique; when two children share a key, only '
+ 'the first child will be used.%s',
KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID))
: void 0;
}
}
if (child != null && keyUnique) {
// 获取child对应的react组件实例,表现为ReactCompositeComponent实例或ReactDomComponent实例等
childInstances[name] = instantiateReactComponent(child, true);
}
}
// 用于装载、更新、或卸载ReactDomComponent子组件
// 被ReactMultiChild模块调用,用于管理ReactDomComponent的子组件节点
var ReactChildReconciler = {
// 获取props.children相关react组件实例集合
instantiateChildren: function (nestedChildNodes, transaction, context, selfDebugID // 0 in production and for roots
) {
if (nestedChildNodes == null) {
return null;
}
var childInstances = {};
if (process.env.NODE_ENV !== 'production') {
traverseAllChildren(nestedChildNodes, function (childInsts, child, name) {
return instantiateChild(childInsts, child, name, selfDebugID);
}, childInstances);
} else {
traverseAllChildren(nestedChildNodes, instantiateChild, childInstances);
}
return childInstances;
},
// 通过shouldUpdateReactComponent函数判断是否可以更新ReactDomComponent子组件;若不能,卸载组件,并装载新的子组件
// 参数prevChildren组件中先前挂载的子节点,以key键作为标识,用于更新或移除
// 参数nextChildren组件中即将挂载的子节点,以key键作为标识,同prevChildren比较后添加或更新
// 参数mountImages更新为组件最终渲染的子节点图谱
// 参数removedNodes更新为组件待移除的子节点
// 参数transcation生命周期管理
// 参数hostParent父节点信息
updateChildren: function (prevChildren, nextChildren, mountImages, removedNodes, transaction, hostParent, hostContainerInfo, context, selfDebugID // 0 in production and for roots
) {
if (!nextChildren && !prevChildren) {
return;
}
var name;
var prevChild;
for (name in nextChildren) {
if (!nextChildren.hasOwnProperty(name)) {
continue;
}
prevChild = prevChildren && prevChildren[name];
var prevElement = prevChild && prevChild._currentElement;
var nextElement = nextChildren[name];
if (prevChild != null && shouldUpdateReactComponent(prevElement, nextElement)) {
ReactReconciler.receiveComponent(prevChild, nextElement, transaction, context);
nextChildren[name] = prevChild;
} else {
if (prevChild) {
removedNodes[name] = ReactReconciler.getHostNode(prevChild);
ReactReconciler.unmountComponent(prevChild, false);
}
var nextChildInstance = instantiateReactComponent(nextElement, true);
nextChildren[name] = nextChildInstance;
var nextChildMountImage = ReactReconciler.mountComponent(nextChildInstance, transaction, hostParent, hostContainerInfo, context, selfDebugID);
mountImages.push(nextChildMountImage);
}
}
for (name in prevChildren) {
if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) {
prevChild = prevChildren[name];
removedNodes[name] = ReactReconciler.getHostNode(prevChild);
ReactReconciler.unmountComponent(prevChild, false);
}
}
},
// 遍历props.children相关react组件实例,执行unmountComponent方法卸载组件
unmountChildren: function (renderedChildren, safely) {
for (var name in renderedChildren) {
if (renderedChildren.hasOwnProperty(name)) {
var renderedChild = renderedChildren[name];
ReactReconciler.unmountComponent(renderedChild, safely);
}
}
}
};
module.exports = ReactChildReconciler;
本文介绍ReactChildReconciler模块的功能,该模块负责挂载、卸载或更新ReactDomComponent子组件。文章详细解释了如何通过不同的函数实现子组件的创建、更新和删除过程。

2737

被折叠的 条评论
为什么被折叠?



