Skip to content

Commit

Permalink
[string-refs] log string ref from prod
Browse files Browse the repository at this point in the history
If passed as a feature flag, this calls the configured function when a string ref is used even from prod code to find the last usages.
  • Loading branch information
kassens committed Oct 10, 2024
1 parent 7b7fac0 commit ee33268
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 20 deletions.
28 changes: 17 additions & 11 deletions packages/react/src/jsx/ReactJSXElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
disableStringRefs,
disableDefaultPropsExceptForClasses,
enableOwnerStacks,
enableLogStringRefsProd,
} from 'shared/ReactFeatureFlags';
import {checkPropStringCoercion} from 'shared/CheckStringCoercion';
import {ClassComponent} from 'react-reconciler/src/ReactWorkTags';
Expand Down Expand Up @@ -76,7 +77,7 @@ let didWarnAboutStringRefs;
let didWarnAboutElementRef;
let didWarnAboutOldJSXRuntime;

if (__DEV__) {
if (__DEV__ || enableLogStringRefsProd) {
didWarnAboutStringRefs = {};
didWarnAboutElementRef = {};
}
Expand Down Expand Up @@ -1314,22 +1315,27 @@ function stringRefAsCallbackRef(stringRef, type, owner, value) {
);
}

if (__DEV__) {
if (__DEV__ || enableLogStringRefsProd) {
if (
// Will already warn with "Function components cannot be given refs"
!(typeof type === 'function' && !isReactClass(type))
) {
const componentName = getComponentNameFromFiber(owner) || 'Component';
if (!didWarnAboutStringRefs[componentName]) {
console.error(
'Component "%s" contains the string ref "%s". Support for string refs ' +
'will be removed in a future major release. We recommend using ' +
'useRef() or createRef() instead. ' +
'Learn more about using refs safely here: ' +
'https://react.dev/link/strict-mode-string-ref',
componentName,
stringRef,
);
if (enableLogStringRefsProd) {
enableLogStringRefsProd(componentName, stringRef);
}
if (__DEV__) {
console.error(
'Component "%s" contains the string ref "%s". Support for string refs ' +
'will be removed in a future major release. We recommend using ' +
'useRef() or createRef() instead. ' +
'Learn more about using refs safely here: ' +
'https://react.dev/link/strict-mode-string-ref',
componentName,
stringRef,
);
}
didWarnAboutStringRefs[componentName] = true;
}
}
Expand Down
7 changes: 7 additions & 0 deletions packages/shared/ReactFeatureFlags.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,13 @@ export const disableClientCache = true;
// during element creation.
export const enableRefAsProp = true;
export const disableStringRefs = true;
/**
* If set to a function, the function will be called with the component name
* and ref string.
*
* NOTE: This happens also in the production build.
*/
export const enableLogStringRefsProd: null | ((string, string) => void) = null;

// Warn on any usage of ReactTestRenderer
export const enableReactTestRendererWarning = true;
Expand Down
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.native-fb.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const enableLazyContextPropagation = true;
export const enableLegacyCache = false;
export const enableLegacyFBSupport = false;
export const enableLegacyHidden = false;
export const enableLogStringRefsProd: null | ((string, string) => void) = null;
export const enableNoCloningMemoCache = false;
export const enableOwnerStacks = false;
export const enablePostpone = false;
Expand Down
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.native-oss.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const enableContextProfiling = false;
export const enableLegacyCache = false;
export const enableLegacyFBSupport = false;
export const enableLegacyHidden = false;
export const enableLogStringRefsProd: null | ((string, string) => void) = null;
export const enableNoCloningMemoCache = false;
export const enableObjectFiber = false;
export const enableOwnerStacks = false;
Expand Down
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.test-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const enableUseEffectEventHook = false;
export const favorSafetyOverHydrationPerf = true;
export const enableComponentStackLocations = true;
export const enableLegacyFBSupport = false;
export const enableLogStringRefsProd: null | ((string, string) => void) = null;
export const enableFilterEmptyStringAttributesDOM = true;
export const enableGetInspectorDataForInstanceInProduction = false;
export const enableFabricCompleteRootInCommitPhase = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const enableUseEffectEventHook = false;
export const favorSafetyOverHydrationPerf = true;
export const enableComponentStackLocations = true;
export const enableLegacyFBSupport = false;
export const enableLogStringRefsProd: null | ((string, string) => void) = null;
export const enableFilterEmptyStringAttributesDOM = true;
export const enableGetInspectorDataForInstanceInProduction = false;
export const enableRenderableContext = false;
Expand Down
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.www-dynamic.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const disableSchedulerTimeoutInWorkLoop = __VARIANT__;
export const enableDeferRootSchedulingToMicrotask = __VARIANT__;
export const enableDO_NOT_USE_disableStrictPassiveEffect = __VARIANT__;
export const enableHiddenSubtreeInsertionEffectCleanup = __VARIANT__;
export const enableLogStringRefsProd: null | ((string, string) => void) = null;
export const enableNoCloningMemoCache = __VARIANT__;
export const enableObjectFiber = __VARIANT__;
export const enableRenderableContext = __VARIANT__;
Expand Down
5 changes: 3 additions & 2 deletions packages/shared/forks/ReactFeatureFlags.www.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,21 @@ export const {
enableDebugTracing,
enableDeferRootSchedulingToMicrotask,
enableDO_NOT_USE_disableStrictPassiveEffect,
enableHiddenSubtreeInsertionEffectCleanup,
enableInfiniteRenderLoopDetection,
enableLogStringRefsProd,
enableNoCloningMemoCache,
enableObjectFiber,
enableRenderableContext,
enableRetryLaneExpiration,
enableSiblingPrerendering,
enableTransitionTracing,
enableTrustedTypesIntegration,
enableHiddenSubtreeInsertionEffectCleanup,
favorSafetyOverHydrationPerf,
renameElementSymbol,
retryLaneExpirationMs,
syncLaneExpirationMs,
transitionLaneExpirationMs,
enableSiblingPrerendering,
} = dynamicFeatureFlags;

// On WWW, __EXPERIMENTAL__ is used for a new modern build.
Expand Down
30 changes: 23 additions & 7 deletions scripts/flags/flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ function getNextMajorFlagValue(flag) {
const value = ReactFeatureFlagsMajor[flag];
if (value === true || value === 'next') {
return '✅';
} else if (value === false || value === 'experimental') {
} else if (value === false || value === null || value === 'experimental') {
return '❌';
} else if (value === 'profile') {
return '📊';
Expand All @@ -189,7 +189,12 @@ function getOSSCanaryFlagValue(flag) {
const value = ReactFeatureFlags[flag];
if (value === true) {
return '✅';
} else if (value === false || value === 'experimental' || value === 'next') {
} else if (
value === false ||
value === null ||
value === 'experimental' ||
value === 'next'
) {
return '❌';
} else if (value === 'profile') {
return '📊';
Expand All @@ -206,7 +211,7 @@ function getOSSExperimentalFlagValue(flag) {
const value = ReactFeatureFlags[flag];
if (value === true || value === 'experimental') {
return '✅';
} else if (value === false || value === 'next') {
} else if (value === false || value === null || value === 'next') {
return '❌';
} else if (value === 'profile') {
return '📊';
Expand All @@ -225,7 +230,7 @@ function getWWWModernFlagValue(flag) {
const value = ReactFeatureFlagsWWW[flag];
if (value === true || value === 'experimental') {
return '✅';
} else if (value === false || value === 'next') {
} else if (value === false || value === null || value === 'next') {
return '❌';
} else if (value === 'profile') {
return '📊';
Expand All @@ -244,7 +249,12 @@ function getWWWClassicFlagValue(flag) {
const value = ReactFeatureFlagsWWW[flag];
if (value === true) {
return '✅';
} else if (value === false || value === 'experimental' || value === 'next') {
} else if (
value === false ||
value === null ||
value === 'experimental' ||
value === 'next'
) {
return '❌';
} else if (value === 'profile') {
return '📊';
Expand All @@ -265,7 +275,7 @@ function getRNNextMajorFlagValue(flag) {
return '✅';
} else if (value === 'next-todo') {
return '📋';
} else if (value === false || value === 'experimental') {
} else if (value === false || value === null || value === 'experimental') {
return '❌';
} else if (value === 'profile') {
return '📊';
Expand All @@ -286,6 +296,7 @@ function getRNOSSFlagValue(flag) {
return '✅';
} else if (
value === false ||
value === null ||
value === 'experimental' ||
value === 'next' ||
value === 'next-todo'
Expand All @@ -308,7 +319,12 @@ function getRNFBFlagValue(flag) {
const value = ReactFeatureFlagsNativeFB[flag];
if (value === true) {
return '✅';
} else if (value === false || value === 'experimental' || value === 'next') {
} else if (
value === false ||
value === null ||
value === 'experimental' ||
value === 'next'
) {
return '❌';
} else if (value === 'profile') {
return '📊';
Expand Down

0 comments on commit ee33268

Please sign in to comment.