Skip to content

Commit fc393ad

Browse files
committed
Boolean props should coerce consistently between HostHoistable and HostComponent and Fizz equivalents
1 parent 8ea96ef commit fc393ad

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,13 @@ export function isHydratableType(type: string, props: Props): boolean {
10271027
if (enableFloat) {
10281028
if (type === 'script') {
10291029
const {async, onLoad, onError} = (props: any);
1030-
return !(async && (onLoad || onError));
1030+
return !(
1031+
!async ||
1032+
onLoad ||
1033+
onError ||
1034+
typeof async === 'function' ||
1035+
typeof async === 'symbol'
1036+
);
10311037
}
10321038
return true;
10331039
} else {
@@ -2455,9 +2461,15 @@ export function getResource(
24552461
return null;
24562462
}
24572463
case 'script': {
2458-
if (typeof pendingProps.src === 'string' && pendingProps.async === true) {
2459-
const scriptProps: ScriptProps = pendingProps;
2460-
const key = getScriptKey(scriptProps.src);
2464+
const async = pendingProps.async;
2465+
const src = pendingProps.src;
2466+
if (
2467+
typeof src === 'string' &&
2468+
async &&
2469+
typeof async !== 'function' &&
2470+
typeof async !== 'symbol'
2471+
) {
2472+
const key = getScriptKey(src);
24612473
const scripts = getResourcesFromRoot(resourceRoot).hoistableScripts;
24622474
24632475
let resource = scripts.get(key);
@@ -3103,15 +3115,24 @@ export function isHostHoistableType(
31033115
}
31043116
case 'script': {
31053117
if (
3106-
props.async !== true ||
3118+
// This is ordered to hopefully hit an exclusion case as early as possible
3119+
// Logically the async checks together form a "truthy and not function/symbol" which is
3120+
// how the prop is serialized on a regular HostComponent
3121+
!props.async ||
31073122
props.onLoad ||
31083123
props.onError ||
3109-
typeof props.src !== 'string' ||
3110-
!props.src
3124+
!props.src ||
3125+
typeof props.async === 'function' ||
3126+
typeof props.async === 'symbol' ||
3127+
typeof props.src !== 'string'
31113128
) {
31123129
if (__DEV__) {
3130+
const isAsync =
3131+
props.async &&
3132+
typeof props.async !== 'function' &&
3133+
typeof props.async !== 'symbol';
31133134
if (outsideHostContainerContext) {
3114-
if (props.async !== true) {
3135+
if (!isAsync) {
31153136
console.error(
31163137
'Cannot render a sync or defer <script> outside the main document without knowing its order.' +
31173138
' Try adding async="" or moving it into the root <head> tag.',

packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2575,7 +2575,13 @@ function pushScript(
25752575

25762576
const src = props.src;
25772577
const key = getResourceKey('script', src);
2578-
if (props.async !== true || props.onLoad || props.onError) {
2578+
2579+
const isAsync =
2580+
props.async &&
2581+
typeof props.async !== 'function' &&
2582+
typeof props.async !== 'symbol';
2583+
2584+
if (!isAsync || props.onLoad || props.onError) {
25792585
// we don't want to preload nomodule scripts
25802586
if (props.noModule !== true) {
25812587
// We can't resourcify scripts with load listeners. To avoid ambiguity with
@@ -2600,7 +2606,7 @@ function pushScript(
26002606
}
26012607
}
26022608

2603-
if (props.async !== true) {
2609+
if (!isAsync) {
26042610
// This is not an async script, we can preloaded it but it still needs to
26052611
// be emitted in place since it needs to hydrate on the client
26062612
pushScriptImpl(target, props);

0 commit comments

Comments
 (0)