in ComponentKit/Core/Render/CKRenderHelpers.mm [166:226]
auto build(id<CKComponentProtocol> component,
CKTreeNode *parent,
CKTreeNode *_Nullable previousParent,
const CKBuildComponentTreeParams ¶ms,
BOOL parentHasStateUpdate) -> void
{
RCCAssertNotNil(component, @"component cannot be nil");
RCCAssertNotNil(parent, @"parent cannot be nil");
// Check if the component already has a tree node.
CKTreeNode *node = component.treeNode;
[node linkComponent:component toParent:parent inScopeRoot:params.scopeRoot];
unsigned int numberOfChildren = [component numberOfChildren];
if (numberOfChildren == 0) {
return;
}
// The assumption was that if there was no previous parent this node couldn't
// possibly have a state update. In reality this can happen if the previous generation
// didn't contain a render component (thus the second phase wouldn't have been performed
// and component aren't linked). A state update on a first generation's non reusable
// component introducing a reusable component would lead to an incorrect `parentHasStateUpdate`
// value.
id previousParentOrComponent = params.previousScopeRoot.hasRenderComponentInTree == NO ? (id)component : previousParent;
// Update the `parentHasStateUpdate` param for Faster state/props updates.
// TODO: Share this value with the value precomputed in the scope
parentHasStateUpdate = parentHasStateUpdate ||
(params.buildTrigger == CKBuildTriggerStateUpdate &&
CKRender::componentHasStateUpdate(node,
previousParentOrComponent,
params.buildTrigger,
params.stateUpdates));
// If there is a node, we update the parents' pointers to the next level in the tree.
if (node) {
parent = node;
previousParent = [previousParent childForComponentKey:[node componentKey]];
// Report information to `debugAnalyticsListener`.
if (numberOfChildren == 1 && params.shouldCollectTreeNodeCreationInformation) {
[params.scopeRoot.analyticsListener didBuildTreeNodeForPrecomputedChild:component
node:node
parent:parent
params:params
parentHasStateUpdate:parentHasStateUpdate];
}
}
for (int i=0; i<numberOfChildren; i++) {
auto const childComponent = (id<CKComponentProtocol>)[component childAtIndex:i];
if (childComponent) {
[childComponent buildComponentTree:parent
previousParent:previousParent
params:params
parentHasStateUpdate:parentHasStateUpdate];
}
}
}