38
enableCache,
39
enableTransitionTracing,
40
enableFloat,
41
+ passChildrenWhenCloningPersistedNodes,
42
} from 'shared/ReactFeatureFlags';
43
44
import {now} from './Scheduler';
259
// children to find all the terminal nodes.
260
let node = workInProgress.child;
261
while (node !== null) {
261
- // eslint-disable-next-line no-labels
262
- branches: if (node.tag === HostComponent) {
262
+ if (node.tag === HostComponent) {
263
let instance = node.stateNode;
264
if (needsVisibilityToggle && isHidden) {
265
// This child is inside a timed out tree. Hide it.
266
const props = node.memoizedProps;
267
const type = node.type;
268
- instance = cloneHiddenInstance(instance, type, props, node);
268
+ instance = cloneHiddenInstance(instance, type, props);
269
}
270
appendInitialChild(parent, instance);
271
} else if (node.tag === HostText) {
273
if (needsVisibilityToggle && isHidden) {
274
// This child is inside a timed out tree. Hide it.
275
const text = node.memoizedProps;
276
- instance = cloneHiddenTextInstance(instance, text, node);
276
+ instance = cloneHiddenTextInstance(instance, text);
277
}
278
appendInitialChild(parent, instance);
279
} else if (node.tag === HostPortal) {
290
if (child !== null) {
291
child.return = node;
292
}
293
- appendAllChildren(parent, node, true, true);
293
+ appendAllChildren(
294
+ parent,
295
+ node,
296
+ /* needsVisibilityToggle */ true,
297
+ /* isHidden */ true,
298
+ );
299
} else if (node.child !== null) {
300
node.child.return = node;
301
node = node.child;
333
let node = workInProgress.child;
334
while (node !== null) {
335
// eslint-disable-next-line no-labels
331
- branches: if (node.tag === HostComponent) {
336
+ if (node.tag === HostComponent) {
337
let instance = node.stateNode;
338
if (needsVisibilityToggle && isHidden) {
339
// This child is inside a timed out tree. Hide it.
340
const props = node.memoizedProps;
341
const type = node.type;
337
- instance = cloneHiddenInstance(instance, type, props, node);
342
+ instance = cloneHiddenInstance(instance, type, props);
343
}
344
appendChildToContainerChildSet(containerChildSet, instance);
345
} else if (node.tag === HostText) {
347
if (needsVisibilityToggle && isHidden) {
348
// This child is inside a timed out tree. Hide it.
349
const text = node.memoizedProps;
345
- instance = cloneHiddenTextInstance(instance, text, node);
350
+ instance = cloneHiddenTextInstance(instance, text);
351
}
352
appendChildToContainerChildSet(containerChildSet, instance);
353
} else if (node.tag === HostPortal) {
369
appendAllChildrenToContainer(
370
containerChildSet,
371
node,
367
- _needsVisibilityToggle,
368
- true,
372
+ /* needsVisibilityToggle */ _needsVisibilityToggle,
373
+ /* isHidden */ true,
374
);
375
} else if (node.child !== null) {
376
node.child.return = node;
395
}
396
}
397
}
398
+
399
function updateHostContainer(current: null | Fiber, workInProgress: Fiber) {
400
if (supportsPersistence) {
401
const portalOrRoot: {
408
// No changes, just reuse the existing instance.
409
} else {
410
const container = portalOrRoot.containerInfo;
405
- const newChildSet = createContainerChildSet(container);
411
+ const newChildSet = createContainerChildSet();
412
// If children might have changed, we have to add them all to the set.
407
- appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
413
+ appendAllChildrenToContainer(
414
+ newChildSet,
415
+ workInProgress,
416
+ /* needsVisibilityToggle */ false,
417
+ /* isHidden */ false,
418
+ );
419
portalOrRoot.pendingChildren = newChildSet;
420
// Schedule an update on the container to swap out the container.
421
markUpdate(workInProgress);
423
}
424
}
425
}
426
+
427
function updateHostComponent(
428
current: Fiber,
429
workInProgress: Fiber,
454
workInProgress.stateNode = currentInstance;
455
return;
456
}
445
- const recyclableInstance: Instance = workInProgress.stateNode;
457
const currentHostContext = getHostContext();
458
+
459
+ let newChildSet = null;
460
+ if (!childrenUnchanged && passChildrenWhenCloningPersistedNodes) {
461
+ newChildSet = createContainerChildSet();
462
+ // If children might have changed, we have to add them all to the set.
463
+ appendAllChildrenToContainer(
464
+ newChildSet,
465
+ workInProgress,
466
+ /* needsVisibilityToggle */ false,
467
+ /* isHidden */ false,
468
+ );
469
+ }
470
+
471
const newInstance = cloneInstance(
472
currentInstance,
473
type,
474
oldProps,
475
newProps,
452
- workInProgress,
476
childrenUnchanged,
454
- recyclableInstance,
477
+ newChildSet,
478
);
479
if (newInstance === currentInstance) {
480
// No changes, just reuse the existing instance.
483
return;
484
}
485
486
+ // Certain renderers require commit-time effects for initial mount.
487
+ // (eg DOM renderer supports auto-focus for certain elements).
488
+ // Make sure such renderers get scheduled for later work.
489
if (
490
finalizeInitialChildren(newInstance, type, newProps, currentHostContext)
491
) {
497
// Even though we're not going to use it for anything.
498
// Otherwise parents won't know that there are new children to propagate upwards.
499
markUpdate(workInProgress);
474
- } else {
500
+ } else if (!passChildrenWhenCloningPersistedNodes) {
501
// If children might have changed, we have to add them all to the set.
476
- appendAllChildren(newInstance, workInProgress, false, false);
502
+ appendAllChildren(
503
+ newInstance,
504
+ workInProgress,
505
+ /* needsVisibilityToggle */ false,
506
+ /* isHidden */ false,
507
+ );
508
}
509
}
510
}
1290
currentHostContext,
1291
workInProgress,
1292
);
1293
+ // TODO: For persistent renderers, we should pass children as part
1294
+ // of the initial instance creation
1295
appendAllChildren(instance, workInProgress, false, false);
1296
workInProgress.stateNode = instance;
1297