From a5cc797b8801dfe58c7a34c99a9fa60c6c9c8274 Mon Sep 17 00:00:00 2001 From: Eric Rozell Date: Thu, 11 Jul 2024 09:47:20 -0700 Subject: [PATCH 1/6] Updates ViewConfig types to delegate isInAParentText context (#29872) ## Summary Now that HostContext determination for Fabric is a DEV-only behavior, we can move the HostContext determination to resolve from the ViewConfig for a given type. Doing this will allow arbitrary types to register themselves as potential parents of raw text string children. This is the first of two diffs for react as we'll: 1. Add the new property to the ViewConfig types 2. Update React Native to include the `supportsRawText` property for `RCTText`, `RCTVirtualText`, `AndroidTextInput`, etc. 3. Switch the behavior of react to read from the ViewConfig rather than a static list of types. ## How did you test this change? - yarn test - yarn test --prod - Pulled change into react-native, added `supportsRawText` props to RCTText, RCTVirtualText, etc. ViewConfigs and confirmed everything type checks. --- packages/react-native-renderer/src/ReactNativeTypes.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/react-native-renderer/src/ReactNativeTypes.js b/packages/react-native-renderer/src/ReactNativeTypes.js index 0b4f9a1045b84..917e3988c7b38 100644 --- a/packages/react-native-renderer/src/ReactNativeTypes.js +++ b/packages/react-native-renderer/src/ReactNativeTypes.js @@ -85,6 +85,7 @@ export type ViewConfig = $ReadOnly<{ }>, ... }>, + supportsRawText?: boolean, uiViewClassName: string, validAttributes: AttributeConfiguration, }>; @@ -92,6 +93,7 @@ export type ViewConfig = $ReadOnly<{ export type PartialViewConfig = $ReadOnly<{ bubblingEventTypes?: $PropertyType, directEventTypes?: $PropertyType, + supportsRawText?: boolean, uiViewClassName: string, validAttributes?: PartialAttributeConfiguration, }>; From a09950ed418adb26a5e735b4ee9eca5e5282ffc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Thu, 11 Jul 2024 13:05:26 -0400 Subject: [PATCH 2/6] Gate inlined consoleWithStackDev transpilation (#30317) This code is getting deleted in #30313 anyway but it should've been gated all along. This code exists to basically manually transpile console.error to consoleWithStackDev because the transpiler doesn't work on `.apply` or `.bind` or the dynamic look up. We only apply the transform in DEV so we should've only done this in DEV. Otherwise these logs get silenced in prod. --- packages/react-client/src/ReactClientConsoleConfigBrowser.js | 4 ++-- packages/react-client/src/ReactClientConsoleConfigPlain.js | 4 ++-- packages/react-client/src/ReactClientConsoleConfigServer.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/react-client/src/ReactClientConsoleConfigBrowser.js b/packages/react-client/src/ReactClientConsoleConfigBrowser.js index a8a375debdc59..a80a410d28d90 100644 --- a/packages/react-client/src/ReactClientConsoleConfigBrowser.js +++ b/packages/react-client/src/ReactClientConsoleConfigBrowser.js @@ -65,9 +65,9 @@ export function printToConsole( ); } - if (methodName === 'error') { + if (methodName === 'error' && __DEV__) { error.apply(console, newArgs); - } else if (methodName === 'warn') { + } else if (methodName === 'warn' && __DEV__) { warn.apply(console, newArgs); } else { // $FlowFixMe[invalid-computed-prop] diff --git a/packages/react-client/src/ReactClientConsoleConfigPlain.js b/packages/react-client/src/ReactClientConsoleConfigPlain.js index 64b61d6ed6f76..45069ea7bd087 100644 --- a/packages/react-client/src/ReactClientConsoleConfigPlain.js +++ b/packages/react-client/src/ReactClientConsoleConfigPlain.js @@ -46,9 +46,9 @@ export function printToConsole( newArgs.splice(offset, 0, badgeFormat, pad + badgeName + pad); } - if (methodName === 'error') { + if (methodName === 'error' && __DEV__) { error.apply(console, newArgs); - } else if (methodName === 'warn') { + } else if (methodName === 'warn' && __DEV__) { warn.apply(console, newArgs); } else { // $FlowFixMe[invalid-computed-prop] diff --git a/packages/react-client/src/ReactClientConsoleConfigServer.js b/packages/react-client/src/ReactClientConsoleConfigServer.js index 0a62707cf6494..8ae8152a08809 100644 --- a/packages/react-client/src/ReactClientConsoleConfigServer.js +++ b/packages/react-client/src/ReactClientConsoleConfigServer.js @@ -66,9 +66,9 @@ export function printToConsole( ); } - if (methodName === 'error') { + if (methodName === 'error' && __DEV__) { error.apply(console, newArgs); - } else if (methodName === 'warn') { + } else if (methodName === 'warn' && __DEV__) { warn.apply(console, newArgs); } else { // $FlowFixMe[invalid-computed-prop] From d09484c4aa746e444268ff8b53763f13f0e4e571 Mon Sep 17 00:00:00 2001 From: Jan Kassens Date: Thu, 11 Jul 2024 13:58:11 -0400 Subject: [PATCH 3/6] Use explicit git hash length in version string (#30318) This avoids potential differences between Git versions. Having a guarantee unique hash isn't neccessary as it's just informational and we have the date in the version string as well. --- scripts/rollup/build-all-release-channels.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/rollup/build-all-release-channels.js b/scripts/rollup/build-all-release-channels.js index 5e8cd27cf5e47..ff6858e422873 100644 --- a/scripts/rollup/build-all-release-channels.js +++ b/scripts/rollup/build-all-release-channels.js @@ -19,9 +19,7 @@ const { // Runs the build script for both stable and experimental release channels, // by configuring an environment variable. -const sha = String( - spawnSync('git', ['show', '-s', '--no-show-signature', '--format=%h']).stdout -).trim(); +const sha = String(spawnSync('git', ['rev-parse', 'HEAD']).stdout).slice(0, 8); let dateString = String( spawnSync('git', [ From af28f480e8e74ce71bb33259b61fef8a5a228f74 Mon Sep 17 00:00:00 2001 From: Jan Kassens Date: Thu, 11 Jul 2024 16:21:12 -0400 Subject: [PATCH 4/6] Feature flag to disable legacy context for function components (#30319) While the goal is to remove legacy context completely, I think we can already land the removal of legacy context for function components. I didn't even know this feature existed until reading the code recently. The win is just a couple of property lookups on function renders, but it trims down the API already as the full removal will likely still take a bit more time. www: Starting with enabled test renderer and a feature flag for production rollout. RN: Not enabled, will follow up on this. --- ...tDOMServerIntegrationLegacyContext-test.js | 24 +++++++++++++++++++ .../__tests__/ReactFunctionComponent-test.js | 2 +- .../src/ReactFiberBeginWork.js | 3 ++- .../src/__tests__/ReactIncremental-test.js | 6 ++--- ...tIncrementalErrorHandling-test.internal.js | 2 +- .../src/__tests__/ReactUse-test.js | 2 +- packages/react-server/src/ReactFizzServer.js | 3 ++- packages/shared/ReactFeatureFlags.js | 8 ++++++- .../forks/ReactFeatureFlags.native-fb.js | 1 + .../forks/ReactFeatureFlags.native-oss.js | 1 + .../forks/ReactFeatureFlags.test-renderer.js | 1 + ...actFeatureFlags.test-renderer.native-fb.js | 1 + .../ReactFeatureFlags.test-renderer.www.js | 1 + .../forks/ReactFeatureFlags.www-dynamic.js | 1 + .../shared/forks/ReactFeatureFlags.www.js | 1 + 15 files changed, 48 insertions(+), 9 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationLegacyContext-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationLegacyContext-test.js index 130bd2310e24a..08551150a7a87 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationLegacyContext-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationLegacyContext-test.js @@ -86,6 +86,9 @@ describe('ReactDOMServerIntegration', () => { }); itRenders('stateless child with context', async render => { + if (gate(flags => flags.disableLegacyContextForFunctionComponents)) { + return; + } function FunctionChildWithContext(props, context) { return
{context.text}
; } @@ -118,6 +121,9 @@ describe('ReactDOMServerIntegration', () => { }); itRenders('stateless child without context', async render => { + if (gate(flags => flags.disableLegacyContextForFunctionComponents)) { + return; + } function FunctionChildWithoutContext(props, context) { // this should render blank; context isn't passed to this component. return
{context.text}
; @@ -151,6 +157,9 @@ describe('ReactDOMServerIntegration', () => { }); itRenders('stateless child with wrong context', async render => { + if (gate(flags => flags.disableLegacyContextForFunctionComponents)) { + return; + } function FunctionChildWithWrongContext(props, context) { // this should render blank; context.text isn't passed to this component. return
{context.text}
; @@ -169,6 +178,9 @@ describe('ReactDOMServerIntegration', () => { }); itRenders('with context passed through to a grandchild', async render => { + if (gate(flags => flags.disableLegacyContextForFunctionComponents)) { + return; + } function Grandchild(props, context) { return
{context.text}
; } @@ -186,6 +198,9 @@ describe('ReactDOMServerIntegration', () => { }); itRenders('a child context overriding a parent context', async render => { + if (gate(flags => flags.disableLegacyContextForFunctionComponents)) { + return; + } const Grandchild = (props, context) => { return
{context.text}
; }; @@ -203,6 +218,9 @@ describe('ReactDOMServerIntegration', () => { }); itRenders('a child context merged with a parent context', async render => { + if (gate(flags => flags.disableLegacyContextForFunctionComponents)) { + return; + } class Parent extends React.Component { getChildContext() { return {text1: 'purple'}; @@ -244,6 +262,9 @@ describe('ReactDOMServerIntegration', () => { itRenders( 'with a call to componentWillMount before getChildContext', async render => { + if (gate(flags => flags.disableLegacyContextForFunctionComponents)) { + return; + } class WillMountContext extends React.Component { getChildContext() { return {text: this.state.text}; @@ -270,6 +291,9 @@ describe('ReactDOMServerIntegration', () => { itRenders( 'if getChildContext exists but childContextTypes is missing with a warning', async render => { + if (gate(flags => flags.disableLegacyContextForFunctionComponents)) { + return; + } function HopefulChild(props, context) { return context.foo || 'nope'; } diff --git a/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js b/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js index d2b1aaa4346d0..6a70f22db917c 100644 --- a/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js +++ b/packages/react-dom/src/__tests__/ReactFunctionComponent-test.js @@ -451,7 +451,7 @@ describe('ReactFunctionComponent', () => { ]); }); - // @gate !disableLegacyContext + // @gate !disableLegacyContext && !disableLegacyContextForFunctionComponents it('should receive context', async () => { class Parent extends React.Component { static childContextTypes = { diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.js b/packages/react-reconciler/src/ReactFiberBeginWork.js index d53ee83777cb0..98a89e018da97 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.js @@ -95,6 +95,7 @@ import { import { debugRenderPhaseSideEffectsForStrictMode, disableLegacyContext, + disableLegacyContextForFunctionComponents, enableProfilerCommitHooks, enableProfilerTimer, enableScopeAPI, @@ -1158,7 +1159,7 @@ function updateFunctionComponent( } let context; - if (!disableLegacyContext) { + if (!disableLegacyContext && !disableLegacyContextForFunctionComponents) { const unmaskedContext = getUnmaskedContext(workInProgress, Component, true); context = getMaskedContext(workInProgress, unmaskedContext); } diff --git a/packages/react-reconciler/src/__tests__/ReactIncremental-test.js b/packages/react-reconciler/src/__tests__/ReactIncremental-test.js index 399e4c01b98cb..50ed1ba5ee9b6 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncremental-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncremental-test.js @@ -1701,7 +1701,7 @@ describe('ReactIncremental', () => { expect(instance.state.n).toEqual(3); }); - // @gate !disableLegacyContext + // @gate !disableLegacyContext && !disableLegacyContextForFunctionComponents it('merges and masks context', async () => { class Intl extends React.Component { static childContextTypes = { @@ -1954,7 +1954,7 @@ describe('ReactIncremental', () => { ]); }); - // @gate !disableLegacyContext + // @gate !disableLegacyContext && !disableLegacyContextForFunctionComponents it('reads context when setState is below the provider', async () => { let statefulInst; @@ -2046,7 +2046,7 @@ describe('ReactIncremental', () => { assertLog([]); }); - // @gate !disableLegacyContext + // @gate !disableLegacyContext && !disableLegacyContextForFunctionComponents it('reads context when setState is above the provider', async () => { let statefulInst; diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js index 91658c562c948..2f0f23dca895b 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js @@ -1158,7 +1158,7 @@ describe('ReactIncrementalErrorHandling', () => { // because it's used for new context, suspense, and many other features. // It has to be tested independently for each feature anyway. So although it // doesn't look like it, this test is specific to legacy context. - // @gate !disableLegacyContext + // @gate !disableLegacyContext && !disableLegacyContextForFunctionComponents it('unwinds the context stack correctly on error', async () => { class Provider extends React.Component { static childContextTypes = {message: PropTypes.string}; diff --git a/packages/react-reconciler/src/__tests__/ReactUse-test.js b/packages/react-reconciler/src/__tests__/ReactUse-test.js index bdc13e0da939d..f648f76aefe53 100644 --- a/packages/react-reconciler/src/__tests__/ReactUse-test.js +++ b/packages/react-reconciler/src/__tests__/ReactUse-test.js @@ -1562,7 +1562,7 @@ describe('ReactUse', () => { expect(root).toMatchRenderedOutput('Async!'); }); - // @gate !disableLegacyContext + // @gate !disableLegacyContext && !disableLegacyContextForFunctionComponents it('unwrap uncached promises in component that accesses legacy context', async () => { class ContextProvider extends React.Component { static childContextTypes = { diff --git a/packages/react-server/src/ReactFizzServer.js b/packages/react-server/src/ReactFizzServer.js index 8fb89f717226f..e068db78dcf8a 100644 --- a/packages/react-server/src/ReactFizzServer.js +++ b/packages/react-server/src/ReactFizzServer.js @@ -152,6 +152,7 @@ import { import ReactSharedInternals from 'shared/ReactSharedInternals'; import { disableLegacyContext, + disableLegacyContextForFunctionComponents, enableScopeAPI, enableSuspenseAvoidThisFallbackFizz, enableCache, @@ -1654,7 +1655,7 @@ function renderFunctionComponent( props: any, ): void { let legacyContext; - if (!disableLegacyContext) { + if (!disableLegacyContext && !disableLegacyContextForFunctionComponents) { legacyContext = getMaskedContext(Component, task.legacyContext); } if (__DEV__) { diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index a3280444766c7..3c2089cb19c13 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -155,8 +155,14 @@ export const transitionLaneExpirationMs = 5000; // Renames the internal symbol for elements since they have changed signature/constructor export const renameElementSymbol = true; -// Removes legacy style context +/** + * Removes legacy style context defined using static `contextTypes` and consumed with static `childContextTypes`. + */ export const disableLegacyContext = true; +/** + * Removes legacy style context just from function components. + */ +export const disableLegacyContextForFunctionComponents = true; // Not ready to break experimental yet. // Modern behaviour aligns more with what components diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 0939b459a9b40..d2a67032cedff 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -37,6 +37,7 @@ export const disableCommentsAsDOMContainers = true; export const disableIEWorkarounds = true; export const disableInputAttributeSyncing = false; export const disableLegacyContext = false; +export const disableLegacyContextForFunctionComponents = false; export const disableLegacyMode = false; export const disableSchedulerTimeoutInWorkLoop = false; export const disableStringRefs = true; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 031f20247eda2..15caf9713bf75 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -28,6 +28,7 @@ export const disableDefaultPropsExceptForClasses = true; export const disableIEWorkarounds = true; export const disableInputAttributeSyncing = false; export const disableLegacyContext = true; +export const disableLegacyContextForFunctionComponents = true; export const disableLegacyMode = false; export const disableSchedulerTimeoutInWorkLoop = false; export const disableStringRefs = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 172335d7cc735..5b01abdb496bf 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -92,6 +92,7 @@ export const disableStringRefs = true; export const enableFastJSX = true; export const disableLegacyMode = true; export const disableLegacyContext = true; +export const disableLegacyContextForFunctionComponents = true; export const enableRenderableContext = true; export const enableReactTestRendererWarning = true; export const disableDefaultPropsExceptForClasses = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js index cea3b6ada831d..d5429617569ca 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js @@ -20,6 +20,7 @@ export const disableDefaultPropsExceptForClasses = false; export const disableIEWorkarounds = true; export const disableInputAttributeSyncing = false; export const disableLegacyContext = false; +export const disableLegacyContextForFunctionComponents = false; export const disableLegacyMode = false; export const disableSchedulerTimeoutInWorkLoop = false; export const disableStringRefs = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index bdc43fd844294..026c2be4f8c67 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -32,6 +32,7 @@ export const enableScopeAPI = true; export const enableCreateEventHandleAPI = false; export const enableSuspenseCallback = true; export const disableLegacyContext = false; +export const disableLegacyContextForFunctionComponents = false; export const enableTrustedTypesIntegration = false; export const disableTextareaChildren = false; export const enableSuspenseAvoidThisFallback = true; diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index 9c6e40b373827..34a8ff82fa32a 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -15,6 +15,7 @@ export const alwaysThrottleRetries = true; export const disableDefaultPropsExceptForClasses = __VARIANT__; +export const disableLegacyContextForFunctionComponents = __VARIANT__; export const disableLegacyMode = __VARIANT__; export const disableSchedulerTimeoutInWorkLoop = __VARIANT__; export const enableAddPropertiesFastPath = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index 00105c2ff6263..3671f40ad8d31 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -17,6 +17,7 @@ const dynamicFeatureFlags: DynamicFeatureFlags = require('ReactFeatureFlags'); export const { alwaysThrottleRetries, disableDefaultPropsExceptForClasses, + disableLegacyContextForFunctionComponents, disableSchedulerTimeoutInWorkLoop, enableAddPropertiesFastPath, enableDebugTracing, From 433068eece2071a96de98b60f99ce6a9121a629c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Thu, 11 Jul 2024 18:34:41 -0400 Subject: [PATCH 5/6] Remove top stack frame from getCurrentStack (#30306) The full stack is the current execution stack (`new Error().stack`) + the current owner stack (`React.captureOwnerStack()`). The idea with the top frame was that when we append it to console.error we'd include both since otherwise the true reason would be obscured behind the little `>` to expand. So we'd just put both stack front and center. By adding this into getCurrentStack it was easy to use the same filtering. I never implemented in Fizz or Flight though. However, with the public API `React.captureOwnerStack()` it's not necessary to include the current stack since you already have it and you'd have filtering capabilities in user space too. Since I'm removing the component stacks from React itself we no longer need this. It's expected that maybe RDT or framework polyfill would include this same technique though. --- .../react-reconciler/src/ReactCurrentFiber.js | 4 ++-- .../src/ReactFiberComponentStack.js | 16 +--------------- .../src/__tests__/ReactLazy-test.internal.js | 14 +++++++++----- packages/react/src/ReactOwnerStack.js | 2 +- packages/react/src/ReactSharedInternalsClient.js | 6 ++---- packages/react/src/ReactSharedInternalsServer.js | 6 ++---- packages/shared/forks/consoleWithStackDev.rn.js | 8 ++++---- packages/shared/forks/consoleWithStackDev.www.js | 8 ++++---- 8 files changed, 25 insertions(+), 39 deletions(-) diff --git a/packages/react-reconciler/src/ReactCurrentFiber.js b/packages/react-reconciler/src/ReactCurrentFiber.js index 29431a8a0aa03..18406d991909a 100644 --- a/packages/react-reconciler/src/ReactCurrentFiber.js +++ b/packages/react-reconciler/src/ReactCurrentFiber.js @@ -33,7 +33,7 @@ export function getCurrentFiberOwnerNameInDevOrNull(): string | null { return null; } -function getCurrentFiberStackInDev(stack: null | Error): string { +function getCurrentFiberStackInDev(): string { if (__DEV__) { if (current === null) { return ''; @@ -43,7 +43,7 @@ function getCurrentFiberStackInDev(stack: null | Error): string { // TODO: The above comment is not actually true. We might be // in a commit phase or preemptive set state callback. if (enableOwnerStacks) { - return getOwnerStackByFiberInDev(current, stack); + return getOwnerStackByFiberInDev(current); } return getStackByFiberInDevAndProd(current); } diff --git a/packages/react-reconciler/src/ReactFiberComponentStack.js b/packages/react-reconciler/src/ReactFiberComponentStack.js index a06411acadd3e..a3063e2b21368 100644 --- a/packages/react-reconciler/src/ReactFiberComponentStack.js +++ b/packages/react-reconciler/src/ReactFiberComponentStack.js @@ -91,27 +91,13 @@ function describeFunctionComponentFrameWithoutLineNumber(fn: Function): string { return name ? describeBuiltInComponentFrame(name) : ''; } -export function getOwnerStackByFiberInDev( - workInProgress: Fiber, - topStack: null | Error, -): string { +export function getOwnerStackByFiberInDev(workInProgress: Fiber): string { if (!enableOwnerStacks || !__DEV__) { return ''; } try { let info = ''; - if (topStack) { - // Prefix with a filtered version of the currently executing - // stack. This information will be available in the native - // stack regardless but it's hidden since we're reprinting - // the stack on top of it. - const formattedTopStack = formatOwnerStack(topStack); - if (formattedTopStack !== '') { - info += '\n' + formattedTopStack; - } - } - if (workInProgress.tag === HostText) { // Text nodes never have an owner/stack because they're not created through JSX. // We use the parent since text nodes are always created through a host parent. diff --git a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js index d4eeb4f13f0a0..644913a15fd9f 100644 --- a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js @@ -213,14 +213,18 @@ describe('ReactLazy', () => { unstable_isConcurrent: true, }); + function App() { + return ( + }> + + + ); + } + let error; try { await act(() => { - root.update( - }> - - , - ); + root.update(); }); } catch (e) { error = e; diff --git a/packages/react/src/ReactOwnerStack.js b/packages/react/src/ReactOwnerStack.js index f6944b08cde32..4746c3a7c6f48 100644 --- a/packages/react/src/ReactOwnerStack.js +++ b/packages/react/src/ReactOwnerStack.js @@ -20,5 +20,5 @@ export function captureOwnerStack(): null | string { } // The current stack will be the owner stack if enableOwnerStacks is true // which it is always here. Otherwise it's the parent stack. - return getCurrentStack(null); + return getCurrentStack(); } diff --git a/packages/react/src/ReactSharedInternalsClient.js b/packages/react/src/ReactSharedInternalsClient.js index 8b00f98a51bf3..452bd933dab06 100644 --- a/packages/react/src/ReactSharedInternalsClient.js +++ b/packages/react/src/ReactSharedInternalsClient.js @@ -35,7 +35,7 @@ export type SharedStateClient = { thrownErrors: Array, // ReactDebugCurrentFrame - getCurrentStack: null | ((stack: null | Error) => string), + getCurrentStack: null | (() => string), }; export type RendererTask = boolean => RendererTask | null; @@ -54,9 +54,7 @@ if (__DEV__) { ReactSharedInternals.didUsePromise = false; ReactSharedInternals.thrownErrors = []; // Stack implementation injected by the current renderer. - ReactSharedInternals.getCurrentStack = (null: - | null - | ((stack: null | Error) => string)); + ReactSharedInternals.getCurrentStack = (null: null | (() => string)); } export default ReactSharedInternals; diff --git a/packages/react/src/ReactSharedInternalsServer.js b/packages/react/src/ReactSharedInternalsServer.js index 0bfeb26fb8007..d670fa18fe770 100644 --- a/packages/react/src/ReactSharedInternalsServer.js +++ b/packages/react/src/ReactSharedInternalsServer.js @@ -38,7 +38,7 @@ export type SharedStateServer = { // DEV-only // ReactDebugCurrentFrame - getCurrentStack: null | ((stack: null | Error) => string), + getCurrentStack: null | (() => string), }; export type RendererTask = boolean => RendererTask | null; @@ -58,9 +58,7 @@ if (enableTaint) { if (__DEV__) { // Stack implementation injected by the current renderer. - ReactSharedInternals.getCurrentStack = (null: - | null - | ((stack: null | Error) => string)); + ReactSharedInternals.getCurrentStack = (null: null | (() => string)); } export default ReactSharedInternals; diff --git a/packages/shared/forks/consoleWithStackDev.rn.js b/packages/shared/forks/consoleWithStackDev.rn.js index 6b567a446a647..44767992cdd86 100644 --- a/packages/shared/forks/consoleWithStackDev.rn.js +++ b/packages/shared/forks/consoleWithStackDev.rn.js @@ -23,7 +23,7 @@ export function setSuppressWarning(newSuppressWarning) { export function warn(format, ...args) { if (__DEV__) { if (!suppressWarning) { - printWarning('warn', format, args, new Error('react-stack-top-frame')); + printWarning('warn', format, args); } } } @@ -31,17 +31,17 @@ export function warn(format, ...args) { export function error(format, ...args) { if (__DEV__) { if (!suppressWarning) { - printWarning('error', format, args, new Error('react-stack-top-frame')); + printWarning('error', format, args); } } } export let isWritingAppendedStack = false; -function printWarning(level, format, args, currentStack) { +function printWarning(level, format, args) { if (__DEV__) { if (ReactSharedInternals.getCurrentStack) { - const stack = ReactSharedInternals.getCurrentStack(currentStack); + const stack = ReactSharedInternals.getCurrentStack(); if (stack !== '') { isWritingAppendedStack = true; format += '%s'; diff --git a/packages/shared/forks/consoleWithStackDev.www.js b/packages/shared/forks/consoleWithStackDev.www.js index 5f04f36359fad..c4311efe09f2a 100644 --- a/packages/shared/forks/consoleWithStackDev.www.js +++ b/packages/shared/forks/consoleWithStackDev.www.js @@ -18,7 +18,7 @@ export function setSuppressWarning(newSuppressWarning) { export function warn(format, ...args) { if (__DEV__) { if (!suppressWarning) { - printWarning('warn', format, args, new Error('react-stack-top-frame')); + printWarning('warn', format, args); } } } @@ -26,19 +26,19 @@ export function warn(format, ...args) { export function error(format, ...args) { if (__DEV__) { if (!suppressWarning) { - printWarning('error', format, args, new Error('react-stack-top-frame')); + printWarning('error', format, args); } } } -function printWarning(level, format, args, currentStack) { +function printWarning(level, format, args) { if (__DEV__) { const React = require('react'); const ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; // Defensive in case this is fired before React is initialized. if (ReactSharedInternals != null && ReactSharedInternals.getCurrentStack) { - const stack = ReactSharedInternals.getCurrentStack(currentStack); + const stack = ReactSharedInternals.getCurrentStack(); if (stack !== '') { format += '%s'; args.push(stack); From 5dcf3ca8d45a276a8b4cee0cedd234967661ca35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Thu, 11 Jul 2024 18:44:49 -0400 Subject: [PATCH 6/6] Add FB RSC Entry for React Package (#30310) I noticed that the www-modern builds pick up the `.experimental.js` entry points but these flags that are associated with these exports are not enabled in www, so it gets the wrong builds. This file is just a clone over the stable `ReactServer.js` one. We should probably do the reexport pattern instead. --- packages/react/src/ReactServer.fb.js | 60 ++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 packages/react/src/ReactServer.fb.js diff --git a/packages/react/src/ReactServer.fb.js b/packages/react/src/ReactServer.fb.js new file mode 100644 index 0000000000000..d6702023e4741 --- /dev/null +++ b/packages/react/src/ReactServer.fb.js @@ -0,0 +1,60 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +export {default as __SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE} from './ReactSharedInternalsServer'; + +import {forEach, map, count, toArray, only} from './ReactChildren'; +import { + REACT_FRAGMENT_TYPE, + REACT_PROFILER_TYPE, + REACT_STRICT_MODE_TYPE, + REACT_SUSPENSE_TYPE, +} from 'shared/ReactSymbols'; +import { + cloneElement, + createElement, + isValidElement, +} from './jsx/ReactJSXElement'; +import {createRef} from './ReactCreateRef'; +import {use, useId, useCallback, useDebugValue, useMemo} from './ReactHooks'; +import {forwardRef} from './ReactForwardRef'; +import {lazy} from './ReactLazy'; +import {memo} from './ReactMemo'; +import {cache} from './ReactCacheServer'; +import version from 'shared/ReactVersion'; + +const Children = { + map, + forEach, + count, + toArray, + only, +}; + +export { + Children, + REACT_FRAGMENT_TYPE as Fragment, + REACT_PROFILER_TYPE as Profiler, + REACT_STRICT_MODE_TYPE as StrictMode, + REACT_SUSPENSE_TYPE as Suspense, + cloneElement, + createElement, + createRef, + use, + forwardRef, + isValidElement, + lazy, + memo, + cache, + useId, + useCallback, + useDebugValue, + useMemo, + version, +};