Skip to content

Commit 8e7abcd

Browse files
javachefacebook-github-bot
authored andcommitted
Support passing in children directly when cloning nodes (facebook#39817)
Summary: Update the UIManagerBinding interface to support the upcoming API changes in facebook/react#27458 Changelog: [Internal] Reviewed By: rubennorte, sammy-SC Differential Revision: D49912532
1 parent 9252099 commit 8e7abcd

File tree

2 files changed

+48
-23
lines changed

2 files changed

+48
-23
lines changed

packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ jsi::Value UIManagerBinding::get(
329329

330330
// Semantic: Clones the node with *same* props and *empty* children.
331331
if (methodName == "cloneNodeWithNewChildren") {
332-
auto paramCount = 1;
332+
auto paramCount = 2;
333333
return jsi::Function::createFromHostFunction(
334334
runtime,
335335
name,
@@ -345,7 +345,8 @@ jsi::Value UIManagerBinding::get(
345345
runtime,
346346
uiManager->cloneNode(
347347
*shadowNodeFromValue(runtime, arguments[0]),
348-
ShadowNode::emptySharedShadowNodeSharedList()));
348+
count > 1 ? shadowNodeListFromValue(runtime, arguments[1])
349+
: ShadowNode::emptySharedShadowNodeSharedList()));
349350
});
350351
}
351352

@@ -363,7 +364,7 @@ jsi::Value UIManagerBinding::get(
363364
size_t count) -> jsi::Value {
364365
validateArgumentCount(runtime, methodName, paramCount, count);
365366

366-
const auto& rawProps = RawProps(runtime, arguments[1]);
367+
RawProps rawProps(runtime, arguments[1]);
367368
return valueFromShadowNode(
368369
runtime,
369370
uiManager->cloneNode(
@@ -375,7 +376,7 @@ jsi::Value UIManagerBinding::get(
375376

376377
// Semantic: Clones the node with *given* props and *empty* children.
377378
if (methodName == "cloneNodeWithNewChildrenAndProps") {
378-
auto paramCount = 2;
379+
auto paramCount = 3;
379380
return jsi::Function::createFromHostFunction(
380381
runtime,
381382
name,
@@ -387,12 +388,16 @@ jsi::Value UIManagerBinding::get(
387388
size_t count) -> jsi::Value {
388389
validateArgumentCount(runtime, methodName, paramCount, count);
389390

390-
const auto& rawProps = RawProps(runtime, arguments[1]);
391+
bool hasChildrenArg = count == 3;
392+
393+
RawProps rawProps(runtime, arguments[hasChildrenArg ? 2 : 1]);
391394
return valueFromShadowNode(
392395
runtime,
393396
uiManager->cloneNode(
394397
*shadowNodeFromValue(runtime, arguments[0]),
395-
ShadowNode::emptySharedShadowNodeSharedList(),
398+
hasChildrenArg
399+
? shadowNodeListFromValue(runtime, arguments[1])
400+
: ShadowNode::emptySharedShadowNodeSharedList(),
396401
&rawProps));
397402
});
398403
}
@@ -417,6 +422,7 @@ jsi::Value UIManagerBinding::get(
417422
});
418423
}
419424

425+
// TODO: remove when passChildrenWhenCloningPersistedNodes is rolled out
420426
if (methodName == "createChildSet") {
421427
return jsi::Function::createFromHostFunction(
422428
runtime,
@@ -432,6 +438,7 @@ jsi::Value UIManagerBinding::get(
432438
});
433439
}
434440

441+
// TODO: remove when passChildrenWhenCloningPersistedNodes is rolled out
435442
if (methodName == "appendChildToSet") {
436443
auto paramCount = 2;
437444
return jsi::Function::createFromHostFunction(
@@ -475,17 +482,13 @@ jsi::Value UIManagerBinding::get(
475482
if (!uiManager->backgroundExecutor_ ||
476483
(runtimeSchedulerBinding &&
477484
runtimeSchedulerBinding->getIsSynchronous())) {
478-
auto weakShadowNodeList =
479-
weakShadowNodeListFromValue(runtime, arguments[1]);
480485
auto shadowNodeList =
481-
shadowNodeListFromWeakList(weakShadowNodeList);
482-
if (shadowNodeList) {
483-
uiManager->completeSurface(
484-
surfaceId,
485-
shadowNodeList,
486-
{/* .enableStateReconciliation = */ true,
487-
/* .mountSynchronously = */ false});
488-
}
486+
shadowNodeListFromValue(runtime, arguments[1]);
487+
uiManager->completeSurface(
488+
surfaceId,
489+
shadowNodeList,
490+
{/* .enableStateReconciliation = */ true,
491+
/* .mountSynchronously = */ false});
489492
} else {
490493
auto weakShadowNodeList =
491494
weakShadowNodeListFromValue(runtime, arguments[1]);

packages/react-native/ReactCommon/react/renderer/uimanager/primitives.h

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,39 @@ inline static jsi::Value valueFromShadowNode(
8686
}
8787
}
8888

89+
// TODO: once we no longer need to mutate the return value (appendChildToSet)
90+
// make this a SharedListOfShared
8991
inline static ShadowNode::UnsharedListOfShared shadowNodeListFromValue(
9092
jsi::Runtime& runtime,
9193
const jsi::Value& value) {
92-
if (CoreFeatures::useNativeState) {
93-
return value.getObject(runtime)
94-
.getNativeState<ShadowNodeListWrapper>(runtime)
95-
->shadowNodeList;
94+
// TODO: cleanup when passChildrenWhenCloningPersistedNodes is rolled out
95+
jsi::Object object = value.asObject(runtime);
96+
if (object.isArray(runtime)) {
97+
auto jsArray = std::move(object).asArray(runtime);
98+
size_t jsArrayLen = jsArray.length(runtime);
99+
if (jsArrayLen > 0) {
100+
auto shadowNodeArray = std::make_shared<ShadowNode::ListOfShared>();
101+
shadowNodeArray->reserve(jsArrayLen);
102+
103+
for (size_t i = 0; i < jsArrayLen; i++) {
104+
shadowNodeArray->push_back(
105+
shadowNodeFromValue(runtime, jsArray.getValueAtIndex(runtime, i)));
106+
}
107+
return shadowNodeArray;
108+
} else {
109+
// TODO: return ShadowNode::emptySharedShadowNodeSharedList()
110+
return std::make_shared<ShadowNode::ListOfShared>(
111+
ShadowNode::ListOfShared({}));
112+
;
113+
}
96114
} else {
97-
return value.getObject(runtime)
98-
.getHostObject<ShadowNodeListWrapper>(runtime)
99-
->shadowNodeList;
115+
if (CoreFeatures::useNativeState) {
116+
return object.getNativeState<ShadowNodeListWrapper>(runtime)
117+
->shadowNodeList;
118+
} else {
119+
return object.getHostObject<ShadowNodeListWrapper>(runtime)
120+
->shadowNodeList;
121+
}
100122
}
101123
}
102124

0 commit comments

Comments
 (0)