Warn if you pass a hidden prop to Activity (#32916)
Since `hidden` is a prop on arbitrary DOM elements it's a common mistake to think that it would also work that way on `<Activity>` but it doesn't. In fact, we even had this mistakes in our own tests. Maybe there's an argument that we should actually just support it but we also have more modes planned. So this adds a warning. It should also already be covered by TypeScript.
Sebastian Markbåge committed
Apr 15, 2025 at 17:17 UTC
539bbdbd86d9cd342aabde4cb08e398751789103
2 files changed
+42
-2
packages/react-reconciler/src/ReactFiberBeginWork.js
+16
@@ -873,6 +873,22 @@ function updateActivityComponent(
873
renderLanes: Lanes,
874
) {
875
const nextProps: ActivityProps = workInProgress.pendingProps;
876
+ if (__DEV__) {
877
+ const hiddenProp = (nextProps: any).hidden;
878
+ if (hiddenProp !== undefined) {
879
+ console.error(
880
+ '<Activity> doesn\'t accept a hidden prop. Use mode="hidden" instead.\n' +
881
+ '- <Activity %s>\n' +
882
+ '+ <Activity %s>',
883
+ hiddenProp === true
884
+ ? 'hidden'
885
+ : hiddenProp === false
886
+ ? 'hidden={false}'
887
+ : 'hidden={...}',
888
+ hiddenProp ? 'mode="hidden"' : 'mode="visible"',
889
+ );
890
+ }
891
+ }
892
const nextChildren = nextProps.children;
893
const nextMode = nextProps.mode;
894
const mode = workInProgress.mode;
packages/react-reconciler/src/__tests__/Activity-test.js
+26
-2
@@ -732,7 +732,7 @@ describe('Activity', () => {
732
733
const root = ReactNoop.createRoot();
734
await act(() => {
735
- root.render(<Activity hidden={false} />);
735
+ root.render(<Activity />);
736
});
737
assertLog([]);
738
expect(root).toMatchRenderedOutput(null);
@@ -741,7 +741,7 @@ describe('Activity', () => {
741
// Partially render a component
742
startTransition(() => {
743
root.render(
744
- <Activity hidden={false}>
744
+ <Activity>
745
<Child />
746
<Text text="Sibling" />
747
</Activity>,
@@ -1480,4 +1480,28 @@ describe('Activity', () => {
1480
assertLog([]);
1481
expect(root).toMatchRenderedOutput(<span prop={2} />);
1482
});
1483
+
1484
+ // @gate enableActivity
1485
+ it('warns if you pass a hidden prop', async () => {
1486
+ function App() {
1487
+ return (
1488
+ // eslint-disable-next-line react/jsx-boolean-value
1489
+ <Activity hidden>
1490
+ <div />
1491
+ </Activity>
1492
+ );
1493
+ }
1494
+
1495
+ const root = ReactNoop.createRoot();
1496
+ await act(() => {
1497
+ root.render(<App show={true} step={1} />);
1498
+ });
1499
+ assertConsoleErrorDev([
1500
+ '<Activity> doesn\'t accept a hidden prop. Use mode="hidden" instead.\n' +
1501
+ '- <Activity hidden>\n' +
1502
+ '+ <Activity mode="hidden">\n' +
1503
+ ' in Activity (at **)\n' +
1504
+ ' in App (at **)',
1505
+ ]);
1506
+ });
1507
});