77 * @flow
88 */
99
10+ import type { Dispatcher as DispatcherType } from 'react-reconciler/src/ReactInternalTypes' ;
1011import type {
1112 Destination ,
1213 Chunk ,
@@ -29,12 +30,24 @@ import {
2930
3031import {
3132 REACT_BLOCK_TYPE ,
32- REACT_SERVER_BLOCK_TYPE ,
3333 REACT_ELEMENT_TYPE ,
34+ REACT_DEBUG_TRACING_MODE_TYPE ,
35+ REACT_FORWARD_REF_TYPE ,
3436 REACT_FRAGMENT_TYPE ,
3537 REACT_LAZY_TYPE ,
38+ REACT_LEGACY_HIDDEN_TYPE ,
39+ REACT_MEMO_TYPE ,
40+ REACT_OFFSCREEN_TYPE ,
41+ REACT_PROFILER_TYPE ,
42+ REACT_SCOPE_TYPE ,
43+ REACT_SERVER_BLOCK_TYPE ,
44+ REACT_STRICT_MODE_TYPE ,
45+ REACT_SUSPENSE_TYPE ,
46+ REACT_SUSPENSE_LIST_TYPE ,
3647} from 'shared/ReactSymbols' ;
3748
49+ import * as React from 'react' ;
50+ import ReactSharedInternals from 'shared/ReactSharedInternals' ;
3851import invariant from 'shared/invariant' ;
3952
4053type ReactJSONValue =
@@ -74,6 +87,8 @@ export type Request = {
7487 toJSON : ( key : string , value : ReactModel ) => ReactJSONValue ,
7588} ;
7689
90+ const ReactCurrentDispatcher = ReactSharedInternals . ReactCurrentDispatcher ;
91+
7792export function createRequest (
7893 model : ReactModel ,
7994 destination : Destination ,
@@ -110,11 +125,33 @@ function attemptResolveElement(element: React$Element<any>): ReactModel {
110125 return [ REACT_ELEMENT_TYPE , type , element . key , element . props ] ;
111126 } else if ( type [ 0 ] === REACT_SERVER_BLOCK_TYPE ) {
112127 return [ REACT_ELEMENT_TYPE , type , element . key , element . props ] ;
113- } else if ( type === REACT_FRAGMENT_TYPE ) {
128+ } else if (
129+ type === REACT_FRAGMENT_TYPE ||
130+ type === REACT_STRICT_MODE_TYPE ||
131+ type === REACT_PROFILER_TYPE ||
132+ type === REACT_SCOPE_TYPE ||
133+ type === REACT_DEBUG_TRACING_MODE_TYPE ||
134+ type === REACT_LEGACY_HIDDEN_TYPE ||
135+ type === REACT_OFFSCREEN_TYPE ||
136+ // TODO: These are temporary shims
137+ // and we'll want a different behavior.
138+ type === REACT_SUSPENSE_TYPE ||
139+ type === REACT_SUSPENSE_LIST_TYPE
140+ ) {
114141 return element . props . children ;
115- } else {
116- invariant ( false , 'Unsupported type.' ) ;
142+ } else if ( type != null && typeof type === 'object ') {
143+ switch ( type . $$typeof ) {
144+ case REACT_FORWARD_REF_TYPE : {
145+ const render = type . render ;
146+ return render ( props , undefined ) ;
147+ }
148+ case REACT_MEMO_TYPE : {
149+ const nextChildren = React . createElement ( type . type , element . props ) ;
150+ return attemptResolveElement ( nextChildren ) ;
151+ }
152+ }
117153 }
154+ invariant ( false , 'Unsupported type.' ) ;
118155}
119156
120157function pingSegment ( request : Request , segment : Segment ) : void {
@@ -236,9 +273,11 @@ export function resolveModelToJSON(
236273 value !== null &&
237274 value . $$typeof === REACT_ELEMENT_TYPE
238275 ) {
276+ const prevDispatcher = ReactCurrentDispatcher . current ;
239277 // TODO: Concatenate keys of parents onto children.
240278 const element : React$Element < any > = (value: any);
241279 try {
280+ ReactCurrentDispatcher . current = Dispatcher ;
242281 // Attempt to render the server component.
243282 value = attemptResolveElement ( element ) ;
244283 } catch (x) {
@@ -253,6 +292,8 @@ export function resolveModelToJSON(
253292 // Something errored. Don't bother encoding anything up to here.
254293 throw x ;
255294 }
295+ } finally {
296+ ReactCurrentDispatcher . current = prevDispatcher ;
256297 }
257298 }
258299
@@ -378,3 +419,33 @@ export function startFlowing(request: Request): void {
378419 request . flowing = true ;
379420 flushCompletedChunks ( request ) ;
380421}
422+
423+ function unsupportedHook ( ) : void {
424+ invariant ( false , 'This Hook is not supported in Server Components.' ) ;
425+ }
426+
427+ const Dispatcher : DispatcherType = {
428+ useMemo < T > ( nextCreate : ( ) = > T ) : T {
429+ return nextCreate ( ) ;
430+ } ,
431+ useCallback < T > ( callback : T ) : T {
432+ return callback ;
433+ } ,
434+ useDebugValue ( ) : void { } ,
435+ useDeferredValue < T > ( value : T ) : T {
436+ return value ;
437+ } ,
438+ useTransition ( ) : [ ( callback : ( ) = > void ) => void , boolean ] {
439+ return [ ( ) => { } , false ] ;
440+ } ,
441+ readContext : ( unsupportedHook : any ) ,
442+ useContext : ( unsupportedHook : any ) ,
443+ useReducer : ( unsupportedHook : any ) ,
444+ useRef : ( unsupportedHook : any ) ,
445+ useState : ( unsupportedHook : any ) ,
446+ useLayoutEffect : ( unsupportedHook : any ) ,
447+ useImperativeHandle : ( unsupportedHook : any ) ,
448+ useEffect : ( unsupportedHook : any ) ,
449+ useOpaqueIdentifier : ( unsupportedHook : any ) ,
450+ useMutableSource : ( unsupportedHook : any ) ,
451+ } ;
0 commit comments