@@ -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 = NoWork ;
339
337
nextUnitOfWork = createWorkInProgress (
340
338
earliestExpirationRoot . current ,
341
339
earliestExpirationTime ,
342
340
) ;
343
341
}
342
+
343
+ earliestExpirationRoot . completedAt = NoWork ;
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 === NoWork ) {
367
367
// There's no work in this tree.
368
368
return NoWork ;
369
369
}
370
-
371
- if ( completedAt !== NoWork ) {
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 !== NoWork &&
387
- workInProgress . expirationTime <= expirationTime )
388
- ) {
389
- // We have more work. Restart the completed tree.
390
- root . completedAt = NoWork ;
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 NoWork, 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 NoWork ;
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 NoWork ;
408
376
}
409
-
410
377
return expirationTime ;
411
378
}
412
379
@@ -817,16 +784,12 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
817
784
workInProgress = returnFiber ;
818
785
continue ;
819
786
} else {
787
+ // We've reached the root. Mark it as complete.
820
788
const root = workInProgress . stateNode ;
821
- // We've reached the root. Mark the root as complete. Depending on how
822
- // much time we have left, we'll either commit it now or in the
823
- // next frame.
824
- if ( isRootBlocked ( root , nextRenderExpirationTime ) ) {
825
- // The root is blocked from committing. Mark it as complete so we
826
- // know we can commit it later without starting new work.
827
- root . completedAt = nextRenderExpirationTime ;
828
- } else {
829
- // The root is not blocked, so we can commit it now.
789
+ root . completedAt = nextRenderExpirationTime ;
790
+ // If the root isn't blocked, it's ready to commit. If it is blocked,
791
+ // we'll come back to it later.
792
+ if ( ! root . isBlocked ) {
830
793
pendingCommit = workInProgress ;
831
794
}
832
795
processCompletionCallbacks ( root , nextRenderExpirationTime ) ;
@@ -1509,25 +1472,6 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
1509
1472
}
1510
1473
}
1511
1474
1512
- function scheduleRoot ( root : FiberRoot , expirationTime : ExpirationTime ) {
1513
- if ( expirationTime === NoWork ) {
1514
- return ;
1515
- }
1516
-
1517
- if ( ! root . isScheduled ) {
1518
- root . isScheduled = true ;
1519
- if ( lastScheduledRoot ) {
1520
- // Schedule ourselves to the end.
1521
- lastScheduledRoot . nextScheduledRoot = root ;
1522
- lastScheduledRoot = root ;
1523
- } else {
1524
- // We're the only work scheduled.
1525
- nextScheduledRoot = root ;
1526
- lastScheduledRoot = root ;
1527
- }
1528
- }
1529
- }
1530
-
1531
1475
function scheduleUpdate (
1532
1476
fiber : Fiber ,
1533
1477
partialState : mixed ,
@@ -1549,6 +1493,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
1549
1493
isReplace,
1550
1494
isForced,
1551
1495
nextCallback : null ,
1496
+ isTopLevelUnmount : false ,
1552
1497
next : null ,
1553
1498
} ;
1554
1499
insertUpdateIntoFiber ( fiber , update , currentTime ) ;
@@ -1594,35 +1539,45 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
1594
1539
}
1595
1540
1596
1541
let node = fiber ;
1597
- let shouldContinue = true ;
1598
- while ( node !== null && shouldContinue ) {
1599
- // Walk the parent path to the root and update each node's expiration
1600
- // time. Once we reach a node whose expiration matches (and whose
1601
- // alternate's expiration matches) we can exit safely knowing that the
1602
- // rest of the path is correct.
1603
- shouldContinue = false ;
1542
+ while ( node !== null ) {
1604
1543
if (
1605
1544
node . expirationTime === NoWork ||
1606
1545
node . expirationTime > expirationTime
1607
1546
) {
1608
- // Expiration time did not match. Update and keep going.
1609
- shouldContinue = true ;
1610
1547
node . expirationTime = expirationTime ;
1611
1548
}
1612
1549
if ( node . alternate !== null ) {
1613
1550
if (
1614
1551
node . alternate . expirationTime === NoWork ||
1615
1552
node . alternate . expirationTime > expirationTime
1616
1553
) {
1617
- // Expiration time did not match. Update and keep going.
1618
- shouldContinue = true ;
1619
1554
node . alternate . expirationTime = expirationTime ;
1620
1555
}
1621
1556
}
1622
1557
if ( node . return === null ) {
1623
1558
if ( node . tag === HostRoot ) {
1624
1559
const root : FiberRoot = ( node . stateNode : any ) ;
1625
- scheduleRoot ( root , expirationTime ) ;
1560
+
1561
+ // Add the root to the work schedule.
1562
+ if ( expirationTime !== NoWork ) {
1563
+ root . isBlocked = false ;
1564
+ if ( ! root . isScheduled ) {
1565
+ root . isScheduled = true ;
1566
+ if ( lastScheduledRoot ) {
1567
+ // Schedule ourselves to the end.
1568
+ lastScheduledRoot . nextScheduledRoot = root ;
1569
+ lastScheduledRoot = root ;
1570
+ } else {
1571
+ // We're the only work scheduled.
1572
+ nextScheduledRoot = root ;
1573
+ lastScheduledRoot = root ;
1574
+ }
1575
+ }
1576
+ }
1577
+
1578
+ // If we're not current performing work, we need to either start
1579
+ // working now (if the update is synchronous) or schedule a callback
1580
+ // to perform work later.
1626
1581
if ( ! isPerformingWork ) {
1627
1582
const priorityLevel = expirationTimeToPriorityLevel (
1628
1583
mostRecentCurrentTime ,
@@ -1774,6 +1729,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
1774
1729
'Cannot commit while already performing work.' ,
1775
1730
) ;
1776
1731
root . forceExpire = expirationTime ;
1732
+ root . isBlocked = false ;
1777
1733
try {
1778
1734
performWork ( TaskPriority , null ) ;
1779
1735
} finally {
0 commit comments