Skip to content

Commit b77b123

Browse files
authored
Call and Return components should use ReactElement (#11834)
* Call and Return components should use ReactElement ReactChildFiber contains lots of branches that do the same thing for different child types. We can unify them by having more child types be ReactElements. This requires that the `type` and `key` fields are sufficient to determine the identity of the child. The main benefit is decreased file size, especially as we add more component types, like context providers and consumers. This updates Call and Return components to use ReactElement. Portals are left alone for now because their identity includes the host instance. * Move server render invariant for call and return types * Sort ReactElement type checks by most likely * Performance timeline should skip over call components Don't think these were intentionally omitted from the blacklist of component types. I went ahead and updated getComponentName to include special types, even though I don't think they're used anywhere right now. * Remove surrounding brackets from internal display names
1 parent 73265fc commit b77b123

File tree

12 files changed

+195
-366
lines changed

12 files changed

+195
-366
lines changed

packages/react-call-return/src/ReactCallReturn.js

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,33 @@
77
* @flow
88
*/
99

10-
import {REACT_CALL_TYPE, REACT_RETURN_TYPE} from 'shared/ReactSymbols';
10+
import {
11+
REACT_CALL_TYPE,
12+
REACT_RETURN_TYPE,
13+
REACT_ELEMENT_TYPE,
14+
} from 'shared/ReactSymbols';
1115

1216
import type {ReactCall, ReactNodeList, ReactReturn} from 'shared/ReactTypes';
1317

14-
type CallHandler<T> = (props: T, returns: Array<mixed>) => ReactNodeList;
18+
type CallHandler<T, V> = (props: T, returns: Array<V>) => ReactNodeList;
1519

16-
export function unstable_createCall<T>(
17-
children: mixed,
18-
handler: CallHandler<T>,
20+
export function unstable_createCall<T, V>(
21+
children: ReactNodeList,
22+
handler: CallHandler<T, V>,
1923
props: T,
2024
key: ?string = null,
21-
): ReactCall {
25+
): ReactCall<V> {
2226
const call = {
2327
// This tag allow us to uniquely identify this as a React Call
24-
$$typeof: REACT_CALL_TYPE,
28+
$$typeof: REACT_ELEMENT_TYPE,
29+
type: REACT_CALL_TYPE,
2530
key: key == null ? null : '' + key,
26-
children: children,
27-
handler: handler,
28-
props: props,
31+
ref: null,
32+
props: {
33+
props,
34+
handler,
35+
children: children,
36+
},
2937
};
3038

3139
if (__DEV__) {
@@ -39,11 +47,16 @@ export function unstable_createCall<T>(
3947
return call;
4048
}
4149

42-
export function unstable_createReturn(value: mixed): ReactReturn {
50+
export function unstable_createReturn<V>(value: V): ReactReturn<V> {
4351
const returnNode = {
44-
// This tag allow us to uniquely identify this as a React Return
45-
$$typeof: REACT_RETURN_TYPE,
46-
value: value,
52+
// This tag allow us to uniquely identify this as a React Call
53+
$$typeof: REACT_ELEMENT_TYPE,
54+
type: REACT_RETURN_TYPE,
55+
key: null,
56+
ref: null,
57+
props: {
58+
value,
59+
},
4760
};
4861

4962
if (__DEV__) {
@@ -63,7 +76,7 @@ export function unstable_isCall(object: mixed): boolean {
6376
return (
6477
typeof object === 'object' &&
6578
object !== null &&
66-
object.$$typeof === REACT_CALL_TYPE
79+
object.type === REACT_CALL_TYPE
6780
);
6881
}
6982

@@ -74,7 +87,7 @@ export function unstable_isReturn(object: mixed): boolean {
7487
return (
7588
typeof object === 'object' &&
7689
object !== null &&
77-
object.$$typeof === REACT_RETURN_TYPE
90+
object.type === REACT_RETURN_TYPE
7891
);
7992
}
8093

packages/react-dom/src/server/ReactPartialRenderer.js

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -621,11 +621,6 @@ class ReactDOMServerRenderer {
621621
'Portals are not currently supported by the server renderer. ' +
622622
'Render them conditionally so that they only appear on the client render.',
623623
);
624-
invariant(
625-
$$typeof !== REACT_CALL_TYPE && $$typeof !== REACT_RETURN_TYPE,
626-
'The experimental Call and Return types are not currently ' +
627-
'supported by the server renderer.',
628-
);
629624
// Catch-all to prevent an infinite loop if React.Children.toArray() supports some new type.
630625
invariant(
631626
false,
@@ -647,28 +642,37 @@ class ReactDOMServerRenderer {
647642
}
648643
this.stack.push(frame);
649644
return '';
650-
} else if (
651-
((nextChild: any): ReactElement).type === REACT_FRAGMENT_TYPE
652-
) {
653-
const nextChildren = toArray(
654-
((nextChild: any): ReactElement).props.children,
655-
);
656-
const frame: Frame = {
657-
domNamespace: parentNamespace,
658-
children: nextChildren,
659-
childIndex: 0,
660-
context: context,
661-
footer: '',
662-
};
663-
if (__DEV__) {
664-
((frame: any): FrameDev).debugElementStack = [];
665-
}
666-
this.stack.push(frame);
667-
return '';
668-
} else {
669-
// Safe because we just checked it's an element.
670-
const nextElement = ((nextChild: any): ReactElement);
671-
return this.renderDOM(nextElement, context, parentNamespace);
645+
}
646+
// Safe because we just checked it's an element.
647+
const nextElement = ((nextChild: any): ReactElement);
648+
const elementType = nextElement.type;
649+
switch (elementType) {
650+
case REACT_FRAGMENT_TYPE:
651+
const nextChildren = toArray(
652+
((nextChild: any): ReactElement).props.children,
653+
);
654+
const frame: Frame = {
655+
domNamespace: parentNamespace,
656+
children: nextChildren,
657+
childIndex: 0,
658+
context: context,
659+
footer: '',
660+
};
661+
if (__DEV__) {
662+
((frame: any): FrameDev).debugElementStack = [];
663+
}
664+
this.stack.push(frame);
665+
return '';
666+
case REACT_CALL_TYPE:
667+
case REACT_RETURN_TYPE:
668+
invariant(
669+
false,
670+
'The experimental Call and Return types are not currently ' +
671+
'supported by the server renderer.',
672+
);
673+
// eslint-disable-next-line-no-fallthrough
674+
default:
675+
return this.renderDOM(nextElement, context, parentNamespace);
672676
}
673677
}
674678
}

0 commit comments

Comments
 (0)