@@ -1308,6 +1308,55 @@ if (__DEV__) {
1308
1308
return lazyType ;
1309
1309
}
1310
1310
1311
+ function renderFunctionComponent ( request , task , key , Component , props ) {
1312
+ // Reset the task's thenable state before continuing, so that if a later
1313
+ // component suspends we can reuse the same task object. If the same
1314
+ // component suspends again, the thenable state will be restored.
1315
+ var prevThenableState = task . thenableState ;
1316
+ task . thenableState = null ;
1317
+ prepareToUseHooksForComponent ( prevThenableState ) ; // The secondArg is always undefined in Server Components since refs error early.
1318
+
1319
+ var secondArg = undefined ;
1320
+ var result = Component ( props , secondArg ) ;
1321
+
1322
+ if (
1323
+ typeof result === "object" &&
1324
+ result !== null &&
1325
+ typeof result . then === "function"
1326
+ ) {
1327
+ // When the return value is in children position we can resolve it immediately,
1328
+ // to its value without a wrapper if it's synchronously available.
1329
+ var thenable = result ;
1330
+
1331
+ if ( thenable . status === "fulfilled" ) {
1332
+ return thenable . value ;
1333
+ } // TODO: Once we accept Promises as children on the client, we can just return
1334
+ // the thenable here.
1335
+
1336
+ result = createLazyWrapperAroundWakeable ( result ) ;
1337
+ } // Track this element's key on the Server Component on the keyPath context..
1338
+
1339
+ var prevKeyPath = task . keyPath ;
1340
+ var prevImplicitSlot = task . implicitSlot ;
1341
+
1342
+ if ( key !== null ) {
1343
+ // Append the key to the path. Technically a null key should really add the child
1344
+ // index. We don't do that to hold the payload small and implementation simple.
1345
+ task . keyPath = prevKeyPath === null ? key : prevKeyPath + "," + key ;
1346
+ } else if ( prevKeyPath === null ) {
1347
+ // This sequence of Server Components has no keys. This means that it was rendered
1348
+ // in a slot that needs to assign an implicit key. Even if children below have
1349
+ // explicit keys, they should not be used for the outer most key since it might
1350
+ // collide with other slots in that set.
1351
+ task . implicitSlot = true ;
1352
+ }
1353
+
1354
+ var json = renderModelDestructive ( request , task , emptyRoot , "" , result ) ;
1355
+ task . keyPath = prevKeyPath ;
1356
+ task . implicitSlot = prevImplicitSlot ;
1357
+ return json ;
1358
+ }
1359
+
1311
1360
function renderFragment ( request , task , children ) {
1312
1361
if ( task . keyPath !== null ) {
1313
1362
// We have a Server Component that specifies a key but we're now splitting
@@ -1397,74 +1446,30 @@ if (__DEV__) {
1397
1446
// This is a reference to a Client Component.
1398
1447
return renderClientElement ( task , type , key , props ) ;
1399
1448
} // This is a server-side component.
1400
- // Reset the task's thenable state before continuing, so that if a later
1401
- // component suspends we can reuse the same task object. If the same
1402
- // component suspends again, the thenable state will be restored.
1403
-
1404
- var prevThenableState = task . thenableState ;
1405
- task . thenableState = null ;
1406
- prepareToUseHooksForComponent ( prevThenableState ) ;
1407
- var result = type ( props ) ;
1408
1449
1409
- if (
1410
- typeof result === "object" &&
1411
- result !== null &&
1412
- typeof result . then === "function"
1413
- ) {
1414
- // When the return value is in children position we can resolve it immediately,
1415
- // to its value without a wrapper if it's synchronously available.
1416
- var thenable = result ;
1417
-
1418
- if ( thenable . status === "fulfilled" ) {
1419
- return thenable . value ;
1420
- } // TODO: Once we accept Promises as children on the client, we can just return
1421
- // the thenable here.
1422
-
1423
- result = createLazyWrapperAroundWakeable ( result ) ;
1424
- } // Track this element's key on the Server Component on the keyPath context..
1425
-
1426
- var prevKeyPath = task . keyPath ;
1427
- var prevImplicitSlot = task . implicitSlot ;
1428
-
1429
- if ( key !== null ) {
1430
- // Append the key to the path. Technically a null key should really add the child
1431
- // index. We don't do that to hold the payload small and implementation simple.
1432
- task . keyPath = prevKeyPath === null ? key : prevKeyPath + "," + key ;
1433
- } else if ( prevKeyPath === null ) {
1434
- // This sequence of Server Components has no keys. This means that it was rendered
1435
- // in a slot that needs to assign an implicit key. Even if children below have
1436
- // explicit keys, they should not be used for the outer most key since it might
1437
- // collide with other slots in that set.
1438
- task . implicitSlot = true ;
1439
- }
1440
-
1441
- var json = renderModelDestructive ( request , task , emptyRoot , "" , result ) ;
1442
- task . keyPath = prevKeyPath ;
1443
- task . implicitSlot = prevImplicitSlot ;
1444
- return json ;
1450
+ return renderFunctionComponent ( request , task , key , type , props ) ;
1445
1451
} else if ( typeof type === "string" ) {
1446
1452
// This is a host element. E.g. HTML.
1447
1453
return renderClientElement ( task , type , key , props ) ;
1448
1454
} else if ( typeof type === "symbol" ) {
1449
1455
if ( type === REACT_FRAGMENT_TYPE && key === null ) {
1450
1456
// For key-less fragments, we add a small optimization to avoid serializing
1451
1457
// it as a wrapper.
1452
- var _prevImplicitSlot = task . implicitSlot ;
1458
+ var prevImplicitSlot = task . implicitSlot ;
1453
1459
1454
1460
if ( task . keyPath === null ) {
1455
1461
task . implicitSlot = true ;
1456
1462
}
1457
1463
1458
- var _json = renderModelDestructive (
1464
+ var json = renderModelDestructive (
1459
1465
request ,
1460
1466
task ,
1461
1467
emptyRoot ,
1462
1468
"" ,
1463
1469
props . children
1464
1470
) ;
1465
-
1466
- task . implicitSlot = _prevImplicitSlot ;
1467
- return _json ;
1471
+ task . implicitSlot = prevImplicitSlot ;
1472
+ return json ;
1468
1473
} // This might be a built-in React component. We'll let the client decide.
1469
1474
// Any built-in works as long as its props are serializable.
1470
1475
@@ -1484,43 +1489,13 @@ if (__DEV__) {
1484
1489
}
1485
1490
1486
1491
case REACT_FORWARD_REF_TYPE : {
1487
- var render = type . render ; // Reset the task's thenable state before continuing, so that if a later
1488
- // component suspends we can reuse the same task object. If the same
1489
- // component suspends again, the thenable state will be restored.
1490
-
1491
- var _prevThenableState = task . thenableState ;
1492
- task . thenableState = null ;
1493
- prepareToUseHooksForComponent ( _prevThenableState ) ;
1494
-
1495
- var _result = render ( props , undefined ) ;
1496
-
1497
- var _prevKeyPath = task . keyPath ;
1498
- var _prevImplicitSlot2 = task . implicitSlot ;
1499
-
1500
- if ( key !== null ) {
1501
- // Append the key to the path. Technically a null key should really add the child
1502
- // index. We don't do that to hold the payload small and implementation simple.
1503
- task . keyPath =
1504
- _prevKeyPath === null ? key : _prevKeyPath + "," + key ;
1505
- } else if ( _prevKeyPath === null ) {
1506
- // This sequence of Server Components has no keys. This means that it was rendered
1507
- // in a slot that needs to assign an implicit key. Even if children below have
1508
- // explicit keys, they should not be used for the outer most key since it might
1509
- // collide with other slots in that set.
1510
- task . implicitSlot = true ;
1511
- }
1512
-
1513
- var _json2 = renderModelDestructive (
1492
+ return renderFunctionComponent (
1514
1493
request ,
1515
1494
task ,
1516
- emptyRoot ,
1517
- "" ,
1518
- _result
1495
+ key ,
1496
+ type . render ,
1497
+ props
1519
1498
) ;
1520
-
1521
- task . keyPath = _prevKeyPath ;
1522
- task . implicitSlot = _prevImplicitSlot2 ;
1523
- return _json2 ;
1524
1499
}
1525
1500
1526
1501
case REACT_MEMO_TYPE : {
0 commit comments