Skip to content

Commit c13e0c8

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 c13e0c8

File tree

2 files changed

+57
-29
lines changed

2 files changed

+57
-29
lines changed

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

+28-22
Original file line numberDiff line numberDiff line change
@@ -327,25 +327,28 @@ jsi::Value UIManagerBinding::get(
327327
});
328328
}
329329

330-
// Semantic: Clones the node with *same* props and *empty* children.
330+
// Semantic: Clones the node with *same* props and *given* children.
331331
if (methodName == "cloneNodeWithNewChildren") {
332-
auto paramCount = 1;
332+
auto paramCount = 2;
333333
return jsi::Function::createFromHostFunction(
334334
runtime,
335335
name,
336336
paramCount,
337-
[uiManager, methodName, paramCount](
337+
[uiManager, methodName](
338338
jsi::Runtime& runtime,
339339
const jsi::Value& /*thisValue*/,
340340
const jsi::Value* arguments,
341341
size_t count) -> jsi::Value {
342-
validateArgumentCount(runtime, methodName, paramCount, count);
342+
// TODO: re-enable when passChildrenWhenCloningPersistedNodes is
343+
// rolled out
344+
// validateArgumentCount(runtime, methodName, paramCount, count);
343345

344346
return valueFromShadowNode(
345347
runtime,
346348
uiManager->cloneNode(
347349
*shadowNodeFromValue(runtime, arguments[0]),
348-
ShadowNode::emptySharedShadowNodeSharedList()));
350+
count > 1 ? shadowNodeListFromValue(runtime, arguments[1])
351+
: ShadowNode::emptySharedShadowNodeSharedList()));
349352
});
350353
}
351354

@@ -363,7 +366,7 @@ jsi::Value UIManagerBinding::get(
363366
size_t count) -> jsi::Value {
364367
validateArgumentCount(runtime, methodName, paramCount, count);
365368

366-
const auto& rawProps = RawProps(runtime, arguments[1]);
369+
RawProps rawProps(runtime, arguments[1]);
367370
return valueFromShadowNode(
368371
runtime,
369372
uiManager->cloneNode(
@@ -373,26 +376,31 @@ jsi::Value UIManagerBinding::get(
373376
});
374377
}
375378

376-
// Semantic: Clones the node with *given* props and *empty* children.
379+
// Semantic: Clones the node with *given* props and *given* children.
377380
if (methodName == "cloneNodeWithNewChildrenAndProps") {
378-
auto paramCount = 2;
381+
auto paramCount = 3;
379382
return jsi::Function::createFromHostFunction(
380383
runtime,
381384
name,
382385
paramCount,
383-
[uiManager, methodName, paramCount](
386+
[uiManager, methodName](
384387
jsi::Runtime& runtime,
385388
const jsi::Value& /*thisValue*/,
386389
const jsi::Value* arguments,
387390
size_t count) -> jsi::Value {
388-
validateArgumentCount(runtime, methodName, paramCount, count);
391+
// TODO: re-enable when passChildrenWhenCloningPersistedNodes is
392+
// rolled out
393+
// validateArgumentCount(runtime, methodName, paramCount, count);
389394

390-
const auto& rawProps = RawProps(runtime, arguments[1]);
395+
bool hasChildrenArg = count == 3;
396+
RawProps rawProps(runtime, arguments[hasChildrenArg ? 2 : 1]);
391397
return valueFromShadowNode(
392398
runtime,
393399
uiManager->cloneNode(
394400
*shadowNodeFromValue(runtime, arguments[0]),
395-
ShadowNode::emptySharedShadowNodeSharedList(),
401+
hasChildrenArg
402+
? shadowNodeListFromValue(runtime, arguments[1])
403+
: ShadowNode::emptySharedShadowNodeSharedList(),
396404
&rawProps));
397405
});
398406
}
@@ -417,6 +425,7 @@ jsi::Value UIManagerBinding::get(
417425
});
418426
}
419427

428+
// TODO: remove when passChildrenWhenCloningPersistedNodes is rolled out
420429
if (methodName == "createChildSet") {
421430
return jsi::Function::createFromHostFunction(
422431
runtime,
@@ -432,6 +441,7 @@ jsi::Value UIManagerBinding::get(
432441
});
433442
}
434443

444+
// TODO: remove when passChildrenWhenCloningPersistedNodes is rolled out
435445
if (methodName == "appendChildToSet") {
436446
auto paramCount = 2;
437447
return jsi::Function::createFromHostFunction(
@@ -475,17 +485,13 @@ jsi::Value UIManagerBinding::get(
475485
if (!uiManager->backgroundExecutor_ ||
476486
(runtimeSchedulerBinding &&
477487
runtimeSchedulerBinding->getIsSynchronous())) {
478-
auto weakShadowNodeList =
479-
weakShadowNodeListFromValue(runtime, arguments[1]);
480488
auto shadowNodeList =
481-
shadowNodeListFromWeakList(weakShadowNodeList);
482-
if (shadowNodeList) {
483-
uiManager->completeSurface(
484-
surfaceId,
485-
shadowNodeList,
486-
{/* .enableStateReconciliation = */ true,
487-
/* .mountSynchronously = */ false});
488-
}
489+
shadowNodeListFromValue(runtime, arguments[1]);
490+
uiManager->completeSurface(
491+
surfaceId,
492+
shadowNodeList,
493+
{/* .enableStateReconciliation = */ true,
494+
/* .mountSynchronously = */ false});
489495
} else {
490496
auto weakShadowNodeList =
491497
weakShadowNodeListFromValue(runtime, arguments[1]);

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

+29-7
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)