@@ -52,7 +52,6 @@ var {ReactCurrentOwner} = require('ReactGlobalSharedState');
52
52
var getComponentName = require ( 'getComponentName' ) ;
53
53
54
54
var { createWorkInProgress} = require ( 'ReactFiber' ) ;
55
- var { isRootBlocked} = require ( 'ReactFiberRoot' ) ;
56
55
var { onCommitRoot} = require ( 'ReactFiberDevToolsHook' ) ;
57
56
58
57
var {
@@ -335,12 +334,15 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
335
334
'is likely caused by a bug in React. Please file an issue.' ,
336
335
) ;
337
336
} else {
338
- earliestExpirationRoot . completedAt = Done ;
339
337
nextUnitOfWork = createWorkInProgress (
340
338
earliestExpirationRoot . current ,
341
339
earliestExpirationTime ,
342
340
) ;
343
341
}
342
+
343
+ earliestExpirationRoot . completedAt = Done ;
344
+ earliestExpirationRoot . isBlocked = false ;
345
+
344
346
if ( earliestExpirationRoot !== nextRenderedTree ) {
345
347
// We've switched trees. Reset the nested update counter.
346
348
nestedUpdateCount = 0 ;
@@ -360,53 +362,18 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
360
362
// TODO: Find a better name for this function. It also schedules completion
361
363
// callbacks, if a root is blocked.
362
364
function shouldWorkOnRoot ( root : FiberRoot ) : ExpirationTime {
363
- const completedAt = root . completedAt ;
364
365
const expirationTime = root . current . expirationTime ;
365
-
366
366
if ( expirationTime === Done ) {
367
367
// There's no work in this tree.
368
368
return Done ;
369
369
}
370
-
371
- if ( completedAt !== Done ) {
372
- // The root completed but was blocked from committing.
373
- if ( expirationTime < completedAt ) {
374
- // We have work that expires earlier than the completed root.
375
- return expirationTime ;
376
- }
377
-
378
- // If the expiration time of the pending work is equal to the time at
379
- // which we completed the work-in-progress, it's possible additional
380
- // work was scheduled that happens to fall within the same expiration
381
- // bucket. We need to check the work-in-progress fiber.
382
- if ( expirationTime === completedAt ) {
383
- const workInProgress = root . current . alternate ;
384
- if (
385
- workInProgress !== null &&
386
- ( workInProgress . expirationTime !== Done &&
387
- workInProgress . expirationTime <= expirationTime )
388
- ) {
389
- // We have more work. Restart the completed tree.
390
- root . completedAt = Done ;
391
- return expirationTime ;
392
- }
393
- }
394
-
395
- // There have been no higher priority updates since we completed the root.
396
- // If it's still blocked, return Done, as if it has no more work. If it's
397
- // no longer blocked, return the time at which it completed so that we
398
- // can commit it.
399
- if ( isRootBlocked ( root , completedAt ) ) {
400
- // We usually process completion callbacks right after a root is
401
- // completed. But this root already completed, and it's possible that
402
- // we received new completion callbacks since then.
403
- processCompletionCallbacks ( root , completedAt ) ;
404
- return Done ;
405
- }
406
-
407
- return completedAt ;
370
+ if ( root . isBlocked ) {
371
+ // We usually process completion callbacks right after a root is
372
+ // completed. But this root already completed, and it's possible that
373
+ // we received new completion callbacks since then.
374
+ processCompletionCallbacks ( root , root . completedAt ) ;
375
+ return Done ;
408
376
}
409
-
410
377
return expirationTime ;
411
378
}
412
379
@@ -816,16 +783,12 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
816
783
workInProgress = returnFiber ;
817
784
continue ;
818
785
} else {
786
+ // We've reached the root. Mark it as complete.
819
787
const root = workInProgress . stateNode ;
820
- // We've reached the root. Mark the root as complete. Depending on how
821
- // much time we have left, we'll either commit it now or in the
822
- // next frame.
823
- if ( isRootBlocked ( root , nextRenderExpirationTime ) ) {
824
- // The root is blocked from committing. Mark it as complete so we
825
- // know we can commit it later without starting new work.
826
- root . completedAt = nextRenderExpirationTime ;
827
- } else {
828
- // The root is not blocked, so we can commit it now.
788
+ root . completedAt = nextRenderExpirationTime ;
789
+ // If the root isn't blocked, it's ready to commit. If it is blocked,
790
+ // we'll come back to it later.
791
+ if ( ! root . isBlocked ) {
829
792
pendingCommit = workInProgress ;
830
793
}
831
794
processCompletionCallbacks ( root , nextRenderExpirationTime ) ;
@@ -1508,25 +1471,6 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
1508
1471
}
1509
1472
}
1510
1473
1511
- function scheduleRoot ( root : FiberRoot , expirationTime : ExpirationTime ) {
1512
- if ( expirationTime === Done ) {
1513
- return ;
1514
- }
1515
-
1516
- if ( ! root . isScheduled ) {
1517
- root . isScheduled = true ;
1518
- if ( lastScheduledRoot ) {
1519
- // Schedule ourselves to the end.
1520
- lastScheduledRoot . nextScheduledRoot = root ;
1521
- lastScheduledRoot = root ;
1522
- } else {
1523
- // We're the only work scheduled.
1524
- nextScheduledRoot = root ;
1525
- lastScheduledRoot = root ;
1526
- }
1527
- }
1528
- }
1529
-
1530
1474
function scheduleUpdate (
1531
1475
fiber : Fiber ,
1532
1476
partialState : mixed ,
@@ -1548,6 +1492,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
1548
1492
isReplace,
1549
1493
isForced,
1550
1494
nextCallback : null ,
1495
+ isTopLevelUnmount : false ,
1551
1496
next : null ,
1552
1497
} ;
1553
1498
insertUpdateIntoFiber ( fiber , update , currentTime ) ;
@@ -1593,35 +1538,45 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
1593
1538
}
1594
1539
1595
1540
let node = fiber ;
1596
- let shouldContinue = true ;
1597
- while ( node !== null && shouldContinue ) {
1598
- // Walk the parent path to the root and update each node's expiration
1599
- // time. Once we reach a node whose expiration matches (and whose
1600
- // alternate's expiration matches) we can exit safely knowing that the
1601
- // rest of the path is correct.
1602
- shouldContinue = false ;
1541
+ while ( node !== null ) {
1603
1542
if (
1604
1543
node . expirationTime === Done ||
1605
1544
node . expirationTime > expirationTime
1606
1545
) {
1607
- // Expiration time did not match. Update and keep going.
1608
- shouldContinue = true ;
1609
1546
node . expirationTime = expirationTime ;
1610
1547
}
1611
1548
if ( node . alternate !== null ) {
1612
1549
if (
1613
1550
node . alternate . expirationTime === Done ||
1614
1551
node . alternate . expirationTime > expirationTime
1615
1552
) {
1616
- // Expiration time did not match. Update and keep going.
1617
- shouldContinue = true ;
1618
1553
node . alternate . expirationTime = expirationTime ;
1619
1554
}
1620
1555
}
1621
1556
if ( node . return === null ) {
1622
1557
if ( node . tag === HostRoot ) {
1623
1558
const root : FiberRoot = ( node . stateNode : any ) ;
1624
- scheduleRoot ( root , expirationTime ) ;
1559
+
1560
+ // Add the root to the work schedule.
1561
+ if ( expirationTime !== Done ) {
1562
+ root . isBlocked = false ;
1563
+ if ( ! root . isScheduled ) {
1564
+ root . isScheduled = true ;
1565
+ if ( lastScheduledRoot ) {
1566
+ // Schedule ourselves to the end.
1567
+ lastScheduledRoot . nextScheduledRoot = root ;
1568
+ lastScheduledRoot = root ;
1569
+ } else {
1570
+ // We're the only work scheduled.
1571
+ nextScheduledRoot = root ;
1572
+ lastScheduledRoot = root ;
1573
+ }
1574
+ }
1575
+ }
1576
+
1577
+ // If we're not current performing work, we need to either start
1578
+ // working now (if the update is synchronous) or schedule a callback
1579
+ // to perform work later.
1625
1580
if ( ! isPerformingWork ) {
1626
1581
const priorityLevel = expirationTimeToPriorityLevel (
1627
1582
mostRecentCurrentTime ,
@@ -1771,6 +1726,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
1771
1726
'Cannot commit while already performing work.' ,
1772
1727
) ;
1773
1728
root . forceExpire = expirationTime ;
1729
+ root . isBlocked = false ;
1774
1730
try {
1775
1731
performWork ( TaskPriority , null ) ;
1776
1732
} finally {
0 commit comments