Skip to content

Commit cd78e48

Browse files
committed
Disable <div hidden /> API in old fork, too
The motivation for doing this is to make it impossible for additional uses of pre-rendering to sneak into www without going through the LegacyHidden abstraction. Since this feature was already disabled in the new fork, this brings the two closer to parity. The LegacyHidden abstraction itself still needs to opt into pre-rendering somehow, so rather than totally disabling the feature, I updated the `hidden` prop check to be obnoxiously specific. Before, you could set it to any truthy value; now, you must set it to the string "unstable-do-not-use-legacy-hidden". The node will still be hidden in the DOM, since any truthy value will cause the browser to apply a style of `display: none`. I will have to update the LegacyHidden component in www to use the obnoxious string prop. This doesn't block merge, though, since the behavior is gated by a dynamic flag. I will update the component before I enable the flag.
1 parent 9e5b2c9 commit cd78e48

15 files changed

+38
-55
lines changed

packages/react-dom/src/__tests__/ReactUpdates-test.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,19 @@ describe('ReactUpdates', () => {
2929
function LegacyHiddenDiv({hidden, children, ...props}) {
3030
if (gate(flags => flags.new)) {
3131
return (
32-
<div hidden={hidden} {...props}>
32+
<div
33+
hidden={hidden ? 'unstable-do-not-use-legacy-hidden' : false}
34+
{...props}>
3335
<React.unstable_LegacyHidden mode={hidden ? 'hidden' : 'visible'}>
3436
{children}
3537
</React.unstable_LegacyHidden>
3638
</div>
3739
);
3840
} else {
3941
return (
40-
<div hidden={hidden} {...props}>
42+
<div
43+
hidden={hidden ? 'unstable-do-not-use-legacy-hidden' : false}
44+
{...props}>
4145
{children}
4246
</div>
4347
);

packages/react-dom/src/client/ReactDOMHostConfig.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ import {
7878
enableModernEventSystem,
7979
enableCreateEventHandleAPI,
8080
enableScopeAPI,
81+
disableHiddenPropDeprioritization,
8182
} from 'shared/ReactFeatureFlags';
8283
import {HostComponent, HostText} from 'react-reconciler/src/ReactWorkTags';
8384
import {TOP_BEFORE_BLUR, TOP_AFTER_BLUR} from '../events/DOMTopLevelEventTypes';
@@ -372,7 +373,14 @@ export function shouldSetTextContent(type: string, props: Props): boolean {
372373
}
373374

374375
export function shouldDeprioritizeSubtree(type: string, props: Props): boolean {
375-
return !!props.hidden;
376+
if (disableHiddenPropDeprioritization) {
377+
// This is obnoxiously specific so that nobody uses it, but we can still opt
378+
// in via an infra-level userspace abstraction.
379+
return props.hidden === 'unstable-do-not-use-legacy-hidden';
380+
} else {
381+
// Legacy behavior. Any truthy value works.
382+
return !!props.hidden;
383+
}
376384
}
377385

378386
export function createTextInstance(

packages/react-reconciler/src/ReactFiberBeginWork.new.js

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ import {
7575
warnAboutDefaultPropsOnFunctionComponents,
7676
enableScopeAPI,
7777
enableBlocksAPI,
78-
warnAboutDOMHiddenAttribute,
7978
} from 'shared/ReactFeatureFlags';
8079
import invariant from 'shared/invariant';
8180
import shallowEqual from 'shared/shallowEqual';
@@ -1124,22 +1123,6 @@ function updateHostComponent(
11241123
}
11251124

11261125
markRef(current, workInProgress);
1127-
1128-
if (__DEV__) {
1129-
if (
1130-
warnAboutDOMHiddenAttribute &&
1131-
(workInProgress.mode & ConcurrentMode) !== NoMode &&
1132-
nextProps.hasOwnProperty('hidden')
1133-
) {
1134-
// This warning will not be user visible. Only exists so React Core team
1135-
// can find existing callers and migrate them to the new API.
1136-
console.error(
1137-
'Detected use of DOM `hidden` attribute. Should migrate to new API. ' +
1138-
'(owner: React Core)',
1139-
);
1140-
}
1141-
}
1142-
11431126
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
11441127
return workInProgress.child;
11451128
}

packages/react-reconciler/src/ReactFiberBeginWork.old.js

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ import {
6969
warnAboutDefaultPropsOnFunctionComponents,
7070
enableScopeAPI,
7171
enableBlocksAPI,
72-
warnAboutDOMHiddenAttribute,
7372
} from 'shared/ReactFeatureFlags';
7473
import invariant from 'shared/invariant';
7574
import shallowEqual from 'shared/shallowEqual';
@@ -1100,21 +1099,6 @@ function updateHostComponent(current, workInProgress, renderExpirationTime) {
11001099

11011100
markRef(current, workInProgress);
11021101

1103-
if (__DEV__) {
1104-
if (
1105-
warnAboutDOMHiddenAttribute &&
1106-
(workInProgress.mode & ConcurrentMode) !== NoMode &&
1107-
nextProps.hasOwnProperty('hidden')
1108-
) {
1109-
// This warning will not be user visible. Only exists so React Core team
1110-
// can find existing callers and migrate them to the new API.
1111-
console.error(
1112-
'Detected use of DOM `hidden` attribute. Should migrate to new API. ' +
1113-
'(owner: React Core)',
1114-
);
1115-
}
1116-
}
1117-
11181102
// Check the host config to see if the children are offscreen/hidden.
11191103
if (
11201104
workInProgress.mode & ConcurrentMode &&

packages/react-refresh/src/__tests__/ReactFresh-test.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,19 @@ describe('ReactFresh', () => {
7979
function LegacyHiddenDiv({hidden, children, ...props}) {
8080
if (gate(flags => flags.new)) {
8181
return (
82-
<div hidden={hidden} {...props}>
82+
<div
83+
hidden={hidden ? 'unstable-do-not-use-legacy-hidden' : false}
84+
{...props}>
8385
<React.unstable_LegacyHidden mode={hidden ? 'hidden' : 'visible'}>
8486
{children}
8587
</React.unstable_LegacyHidden>
8688
</div>
8789
);
8890
} else {
8991
return (
90-
<div hidden={hidden} {...props}>
92+
<div
93+
hidden={hidden ? 'unstable-do-not-use-legacy-hidden' : false}
94+
{...props}>
9195
{children}
9296
</div>
9397
);

packages/react/src/__tests__/ReactDOMTracing-test.internal.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,19 @@ function loadModules() {
5959
function LegacyHiddenDiv({hidden, children, ...props}) {
6060
if (gate(flags => flags.new)) {
6161
return (
62-
<div hidden={hidden} {...props}>
62+
<div
63+
hidden={hidden ? 'unstable-do-not-use-legacy-hidden' : false}
64+
{...props}>
6365
<React.unstable_LegacyHidden mode={hidden ? 'hidden' : 'visible'}>
6466
{children}
6567
</React.unstable_LegacyHidden>
6668
</div>
6769
);
6870
} else {
6971
return (
70-
<div hidden={hidden} {...props}>
72+
<div
73+
hidden={hidden ? 'unstable-do-not-use-legacy-hidden' : false}
74+
{...props}>
7175
{children}
7276
</div>
7377
);

packages/shared/ReactFeatureFlags.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,4 @@ export const enableLegacyFBSupport = false;
140140
export const deferRenderPhaseUpdateToNextBatch = true;
141141

142142
// Flag used by www build so we can log occurrences of legacy hidden API
143-
export const warnAboutDOMHiddenAttribute = false;
143+
export const disableHiddenPropDeprioritization = true;

packages/shared/forks/ReactFeatureFlags.native-fb.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export const enableFilterEmptyStringAttributesDOM = false;
4848

4949
export const enableNewReconciler = false;
5050
export const deferRenderPhaseUpdateToNextBatch = true;
51-
export const warnAboutDOMHiddenAttribute = false;
51+
export const disableHiddenPropDeprioritization = true;
5252

5353
// Flow magic to verify the exports of this file match the original version.
5454
// eslint-disable-next-line no-unused-vars

packages/shared/forks/ReactFeatureFlags.native-oss.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export const enableFilterEmptyStringAttributesDOM = false;
4747

4848
export const enableNewReconciler = false;
4949
export const deferRenderPhaseUpdateToNextBatch = true;
50-
export const warnAboutDOMHiddenAttribute = false;
50+
export const disableHiddenPropDeprioritization = true;
5151

5252
// Flow magic to verify the exports of this file match the original version.
5353
// eslint-disable-next-line no-unused-vars

packages/shared/forks/ReactFeatureFlags.test-renderer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export const enableFilterEmptyStringAttributesDOM = false;
4747

4848
export const enableNewReconciler = false;
4949
export const deferRenderPhaseUpdateToNextBatch = true;
50-
export const warnAboutDOMHiddenAttribute = false;
50+
export const disableHiddenPropDeprioritization = true;
5151

5252
// Flow magic to verify the exports of this file match the original version.
5353
// eslint-disable-next-line no-unused-vars

0 commit comments

Comments
 (0)