From 4bebe8e2068e3b5071dead2f688786030e145e80 Mon Sep 17 00:00:00 2001 From: yungsters Date: Thu, 30 May 2024 14:30:34 +0000 Subject: [PATCH] Fix `key` Warning for Flattened Positional Children (#29662) ## Summary https://github.com/facebook/react/pull/29088 introduced a regression triggering this warning when rendering flattened positional children: > Each child in a list should have a unique "key" prop. The specific scenario that triggers this is when rendering multiple positional children (which do not require unique `key` props) after flattening them with one of the `React.Children` utilities (e.g. `React.Children.toArray`). The refactored logic in `React.Children` incorrectly drops the `element._store.validated` property in `__DEV__`. This diff fixes the bug and introduces a unit test to prevent future regressions. ## How did you test this change? ``` $ yarn test ReactChildren-test.js ``` DiffTrain build for [72644ef2f2ec7a274f79f6b32320d62757521329](https://github.com/facebook/react/commit/72644ef2f2ec7a274f79f6b32320d62757521329) --- compiled/facebook-www/REVISION | 2 +- compiled/facebook-www/React-dev.classic.js | 11 +++++++++-- compiled/facebook-www/React-dev.modern.js | 11 +++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/compiled/facebook-www/REVISION b/compiled/facebook-www/REVISION index 9ebd9484ba1ad..2d95d72c2050a 100644 --- a/compiled/facebook-www/REVISION +++ b/compiled/facebook-www/REVISION @@ -1 +1 @@ -38e3b23483bf7a612391cd617a8926aa1f3cf52e +72644ef2f2ec7a274f79f6b32320d62757521329 diff --git a/compiled/facebook-www/React-dev.classic.js b/compiled/facebook-www/React-dev.classic.js index c009a90df0ec3..3e960e073da93 100644 --- a/compiled/facebook-www/React-dev.classic.js +++ b/compiled/facebook-www/React-dev.classic.js @@ -22,7 +22,7 @@ if ( ) { __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); } -var ReactVersion = '19.0.0-www-classic-5a597884'; +var ReactVersion = '19.0.0-www-classic-f4a35977'; // Re-export dynamic flags from the www version. var dynamicFeatureFlags = require('ReactFeatureFlags'); @@ -1799,9 +1799,16 @@ function createElement(type, config, children) { return ReactElement(type, key, ref, undefined, undefined, getOwner(), props); } function cloneAndReplaceKey(oldElement, newKey) { - return ReactElement(oldElement.type, newKey, // When enableRefAsProp is on, this argument is ignored. This check only + var clonedElement = ReactElement(oldElement.type, newKey, // When enableRefAsProp is on, this argument is ignored. This check only // exists to avoid the `ref` access warning. enableRefAsProp ? null : oldElement.ref, undefined, undefined, oldElement._owner, oldElement.props); + + { + // The cloned element should inherit the original element's key validation. + clonedElement._store.validated = oldElement._store.validated; + } + + return clonedElement; } /** * Clone and return a new ReactElement using element as the starting point. diff --git a/compiled/facebook-www/React-dev.modern.js b/compiled/facebook-www/React-dev.modern.js index 8ca4bd492946e..3bd76bc60cd09 100644 --- a/compiled/facebook-www/React-dev.modern.js +++ b/compiled/facebook-www/React-dev.modern.js @@ -22,7 +22,7 @@ if ( ) { __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); } -var ReactVersion = '19.0.0-www-modern-c9630b74'; +var ReactVersion = '19.0.0-www-modern-85c20051'; // Re-export dynamic flags from the www version. var dynamicFeatureFlags = require('ReactFeatureFlags'); @@ -1802,9 +1802,16 @@ function createElement(type, config, children) { return ReactElement(type, key, ref, undefined, undefined, getOwner(), props); } function cloneAndReplaceKey(oldElement, newKey) { - return ReactElement(oldElement.type, newKey, // When enableRefAsProp is on, this argument is ignored. This check only + var clonedElement = ReactElement(oldElement.type, newKey, // When enableRefAsProp is on, this argument is ignored. This check only // exists to avoid the `ref` access warning. enableRefAsProp ? null : oldElement.ref, undefined, undefined, oldElement._owner, oldElement.props); + + { + // The cloned element should inherit the original element's key validation. + clonedElement._store.validated = oldElement._store.validated; + } + + return clonedElement; } /** * Clone and return a new ReactElement using element as the starting point.