From a8171274423e1961f0f89d1285d6531df2d64525 Mon Sep 17 00:00:00 2001 From: sebmarkbage Date: Thu, 23 May 2024 16:54:06 +0000 Subject: [PATCH] Move createElement/JSX Warnings into the Renderer (#29088) This is necessary to simplify the component stack handling to make way for owner stacks. It also solves some hacks that we used to have but don't quite make sense. It also solves the problem where things like key warnings get silenced in RSC because they get deduped. It also surfaces areas where we were missing key warnings to begin with. Almost every type of warning is issued from the renderer. React Elements are really not anything special themselves. They're just lazily invoked functions and its really the renderer that determines there semantics. We have three types of warnings that previously fired in JSX/createElement: - Fragment props validation. - Type validation. - Key warning. It's nice to be able to do some validation in the JSX/createElement because it has a more specific stack frame at the callsite. However, that's the case for every type of component and validation. That's the whole point of enableOwnerStacks. It's also not sufficient to do it in JSX/createElement so we also have validation in the renderers too. So this validation is really just an eager validation but also happens again later. The problem with these is that we don't really know what types are valid until we get to the renderer. Additionally, by placing it in the isomorphic code it becomes harder to do deduping of warnings in a way that makes sense for that renderer. It also means we can't reuse logic for managing stacks etc. Fragment props validation really should just be part of the renderer like any other component type. This also matters once we add Fragment refs and other fragment features. So I moved this into Fiber. However, since some Fragments don't have Fibers, I do the validation in ChildFiber instead of beginWork where it would normally happen. For `type` validation we already do validation when rendering. By leaving it to the renderer we don't have to hard code an extra list. This list also varies by context. E.g. class components aren't allowed in RSC but client references are but we don't have an isomorphic way to identify client references because they're defined by the host config so the current logic is flawed anyway. I kept the early validation for now without the `enableOwnerStacks` since it does provide a nicer stack frame but with that flag on it'll be handled with nice stacks anyway. I normalized some of the errors to ensure tests pass. For `key` validation it's the same principle. The mechanism for the heuristic is still the same - if it passes statically through a parent JSX/createElement call then it's considered validated. We already did print the error later from the renderer so this also disables the early log in the `enableOwnerStacks` flag. I also added logging to Fizz so that key warnings can print in SSR logs. Flight is a bit more complex. For elements that end up on the client we just pass the `validated` flag along to the client and let the client renderer print the error once rendered. For server components we log the error from Flight with the server component as the owner on the stack which will allow us to print the right stack for context. The factoring of this is a little tricky because we only want to warn if it's in an array parent but we want to log the error later to get the right debug info. Fiber/Fizz has a similar factoring problem that causes us to create a fake Fiber for the owner which means the logs won't be associated with the right place in DevTools. DiffTrain build for commit https://github.com/facebook/react/commit/84239da896fd7395a667ab1e7ef1ef338a32de8f. --- .../vendor/react/react-is/cjs/ReactIs-dev.js | 6 +- .../cjs/ReactTestRenderer-dev.js | 129 +++++++++++-- .../cjs/ReactTestRenderer-prod.js | 8 +- .../cjs/ReactTestRenderer-profiling.js | 8 +- .../react/react/cjs/JSXDEVRuntime-dev.js | 114 ++++------- .../vendor/react/react/cjs/JSXRuntime-dev.js | 114 ++++------- .../vendor/react/react/cjs/React-dev.js | 177 +++++++----------- .../vendor/react/react/cjs/React-prod.js | 7 +- .../vendor/react/react/cjs/React-profiling.js | 7 +- .../Libraries/Renderer/REVISION | 2 +- .../implementations/ReactFabric-dev.fb.js | 129 +++++++++++-- .../implementations/ReactFabric-prod.fb.js | 8 +- .../ReactFabric-profiling.fb.js | 8 +- .../ReactNativeRenderer-dev.fb.js | 129 +++++++++++-- .../ReactNativeRenderer-prod.fb.js | 8 +- .../ReactNativeRenderer-profiling.fb.js | 8 +- 16 files changed, 529 insertions(+), 333 deletions(-) diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-is/cjs/ReactIs-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-is/cjs/ReactIs-dev.js index 0ffe925a97037..b1aea4f4db071 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-is/cjs/ReactIs-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-is/cjs/ReactIs-dev.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<> */ 'use strict'; @@ -44,7 +44,9 @@ var REACT_MEMO_TYPE = Symbol.for('react.memo'); var REACT_LAZY_TYPE = Symbol.for('react.lazy'); var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen'); -var REACT_CLIENT_REFERENCE = Symbol.for('react.client.reference'); +var REACT_CLIENT_REFERENCE = Symbol.for('react.client.reference'); // This function is deprecated. Don't use. Only the renderer knows what a valid type is. +// TODO: Delete this when enableOwnerStacks ships. + function isValidElementType(type) { if (typeof type === 'string' || typeof type === 'function') { return true; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js index d4ac03f8dd13d..b772d5477d95b 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<98724556db7e01bfefca7439ac7adfc3>> + * @generated SignedSource<<3f7c609322e65db1e2ce38a0f7c72577>> */ 'use strict'; @@ -55,11 +55,14 @@ function printWarning(level, format, args) { // update consoleWithStackDev.www.js as well. { var isErrorLogger = format === '%s\n\n%s\n' || format === '%o\n\n%s\n\n%s\n'; - var stack = ReactSharedInternals.getStackAddendum(); - if (stack !== '') { - format += '%s'; - args = args.concat([stack]); + if (ReactSharedInternals.getCurrentStack) { + var stack = ReactSharedInternals.getCurrentStack(); + + if (stack !== '') { + format += '%s'; + args = args.concat([stack]); + } } if (isErrorLogger) { @@ -5631,7 +5634,7 @@ var warnForMissingKey = function (child, returnFiber) {}; return; } - if (!child._store || child._store.validated || child.key != null) { + if (!child._store || (child._store.validated || child.key != null) && child._store.validated !== 2) { return; } @@ -5640,17 +5643,96 @@ var warnForMissingKey = function (child, returnFiber) {}; } // $FlowFixMe[cannot-write] unable to narrow type from mixed to writable object - child._store.validated = true; - var componentName = getComponentNameFromFiber(returnFiber) || 'Component'; + child._store.validated = 1; + var componentName = getComponentNameFromFiber(returnFiber); + var componentKey = componentName || 'null'; - if (ownerHasKeyUseWarning[componentName]) { + if (ownerHasKeyUseWarning[componentKey]) { return; } - ownerHasKeyUseWarning[componentName] = true; + ownerHasKeyUseWarning[componentKey] = true; + var childOwner = child._owner; + var parentOwner = returnFiber._debugOwner; + var currentComponentErrorInfo = ''; + + if (parentOwner && typeof parentOwner.tag === 'number') { + var name = getComponentNameFromFiber(parentOwner); + + if (name) { + currentComponentErrorInfo = '\n\nCheck the render method of `' + name + '`.'; + } + } + + if (!currentComponentErrorInfo) { + if (componentName) { + currentComponentErrorInfo = "\n\nCheck the top-level render call using <" + componentName + ">."; + } + } // Usually the current owner is the offender, but if it accepts children as a + // property, it may be the creator of the child that's responsible for + // assigning it a key. + + + var childOwnerAppendix = ''; + + if (childOwner != null && parentOwner !== childOwner) { + var ownerName = null; + + if (typeof childOwner.tag === 'number') { + ownerName = getComponentNameFromFiber(childOwner); + } else if (typeof childOwner.name === 'string') { + ownerName = childOwner.name; + } + + if (ownerName) { + // Give the component that originally created this child. + childOwnerAppendix = " It was passed a child from " + ownerName + "."; + } + } // We create a fake Fiber for the child to log the stack trace from. + // TODO: Refactor the warnForMissingKey calls to happen after fiber creation + // so that we can get access to the fiber that will eventually be created. + // That way the log can show up associated with the right instance in DevTools. + + + var fiber = createFiberFromElement(child, returnFiber.mode, 0); + fiber.return = returnFiber; + var prevDebugFiber = getCurrentFiber(); + setCurrentFiber(fiber); + + error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwnerAppendix); - error('Each child in a list should have a unique ' + '"key" prop. See https://react.dev/link/warning-keys for ' + 'more information.'); + setCurrentFiber(prevDebugFiber); }; +} // Given a fragment, validate that it can only be provided with fragment props +// We do this here instead of BeginWork because the Fragment fiber doesn't have +// the whole props object, only the children and is shared with arrays. + + +function validateFragmentProps(element, fiber, returnFiber) { + { + var keys = Object.keys(element.props); + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + + if (key !== 'children' && key !== 'key') { + if (fiber === null) { + // For unkeyed root fragments there's no Fiber. We create a fake one just for + // error stack handling. + fiber = createFiberFromElement(element, returnFiber.mode, 0); + fiber.return = returnFiber; + } + + var prevDebugFiber = getCurrentFiber(); + setCurrentFiber(fiber); + + error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key); + + setCurrentFiber(prevDebugFiber); + break; + } + } + } } function unwrapThenable(thenable) { @@ -5871,7 +5953,9 @@ function createChildReconciler(shouldTrackSideEffects) { var elementType = element.type; if (elementType === REACT_FRAGMENT_TYPE) { - return updateFragment(returnFiber, current, element.props.children, lanes, element.key, debugInfo); + var updated = updateFragment(returnFiber, current, element.props.children, lanes, element.key, debugInfo); + validateFragmentProps(element, updated, returnFiber); + return updated; } if (current !== null) { @@ -6615,6 +6699,7 @@ function createChildReconciler(shouldTrackSideEffects) { existing._debugInfo = debugInfo; } + validateFragmentProps(element, existing, returnFiber); return existing; } } else { @@ -6658,6 +6743,7 @@ function createChildReconciler(shouldTrackSideEffects) { created._debugInfo = debugInfo; } + validateFragmentProps(element, created, returnFiber); return created; } else { var _created4 = createFiberFromElement(element, returnFiber.mode, lanes); @@ -6720,6 +6806,7 @@ function createChildReconciler(shouldTrackSideEffects) { var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null; if (isUnkeyedTopLevelFragment) { + validateFragmentProps(newChild, null, returnFiber); newChild = newChild.props.children; } // Handle object types @@ -23122,10 +23209,22 @@ key, pendingProps, owner, mode, lanes) { } var info = ''; + var typeString; { if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { - info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and " + 'named imports.'; + info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and named imports."; + } + + if (type === null) { + typeString = 'null'; + } else if (isArray(type)) { + typeString = 'array'; + } else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) { + typeString = "<" + (getComponentNameFromType(type.type) || 'Unknown') + " />"; + info = ' Did you accidentally export a JSX literal instead of a component?'; + } else { + typeString = typeof type; } var ownerName = owner ? getComponentNameFromOwner(owner) : null; @@ -23135,7 +23234,7 @@ key, pendingProps, owner, mode, lanes) { } } - throw new Error('Element type is invalid: expected a string (for built-in ' + 'components) or a class/function (for composite components) ' + ("but got: " + (type == null ? type : typeof type) + "." + info)); + throw new Error('Element type is invalid: expected a string (for built-in ' + 'components) or a class/function (for composite components) ' + ("but got: " + typeString + "." + info)); } } } @@ -23344,7 +23443,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-47384982'; +var ReactVersion = '19.0.0-rc-c6122275'; /* * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-prod.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-prod.js index 93261d2835b83..e339f28d972bf 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-prod.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-prod.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<6540b866a6ff4178bae5e8496c9c2dc6>> + * @generated SignedSource<> */ "use strict"; @@ -8774,7 +8774,7 @@ function createFiberFromTypeAndProps( } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - ((null == type ? type : typeof type) + ".") + ((null === type ? "null" : typeof type) + ".") ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -9300,7 +9300,7 @@ var devToolsConfig$jscomp$inline_1042 = { throw Error("TestRenderer does not support findFiberByHostInstance()"); }, bundleType: 0, - version: "19.0.0-rc-59df980e", + version: "19.0.0-rc-382da410", rendererPackageName: "react-test-renderer" }; var internals$jscomp$inline_1229 = { @@ -9331,7 +9331,7 @@ var internals$jscomp$inline_1229 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-59df980e" + reconcilerVersion: "19.0.0-rc-382da410" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1230 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-profiling.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-profiling.js index 78ca489cb86ac..cb21ae0ad4052 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-profiling.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-profiling.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<9640a2643c047b950331599cf3b70c9c>> + * @generated SignedSource<> */ "use strict"; @@ -9412,7 +9412,7 @@ function createFiberFromTypeAndProps( } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - ((null == type ? type : typeof type) + ".") + ((null === type ? "null" : typeof type) + ".") ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -9943,7 +9943,7 @@ var devToolsConfig$jscomp$inline_1105 = { throw Error("TestRenderer does not support findFiberByHostInstance()"); }, bundleType: 0, - version: "19.0.0-rc-98cdfed4", + version: "19.0.0-rc-7fcc15f0", rendererPackageName: "react-test-renderer" }; (function (internals) { @@ -9987,7 +9987,7 @@ var devToolsConfig$jscomp$inline_1105 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-98cdfed4" + reconcilerVersion: "19.0.0-rc-7fcc15f0" }); exports._Scheduler = Scheduler; exports.act = act; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/JSXDEVRuntime-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/JSXDEVRuntime-dev.js index e02c1a8cc5d78..4508d36bcad1f 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/JSXDEVRuntime-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/JSXDEVRuntime-dev.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<10a7ee496c01519458a4d512d4dc4cbf>> + * @generated SignedSource<> */ 'use strict'; @@ -89,11 +89,14 @@ function printWarning(level, format, args) { // update consoleWithStackDev.www.js as well. { var isErrorLogger = format === '%s\n\n%s\n' || format === '%o\n\n%s\n\n%s\n'; - var stack = ReactSharedInternals.getStackAddendum(); - if (stack !== '') { - format += '%s'; - args = args.concat([stack]); + if (ReactSharedInternals.getCurrentStack) { + var stack = ReactSharedInternals.getCurrentStack(); + + if (stack !== '') { + format += '%s'; + args = args.concat([stack]); + } } if (isErrorLogger) { @@ -305,7 +308,9 @@ function checkKeyStringCoercion(value) { } } -var REACT_CLIENT_REFERENCE$1 = Symbol.for('react.client.reference'); +var REACT_CLIENT_REFERENCE$1 = Symbol.for('react.client.reference'); // This function is deprecated. Don't use. Only the renderer knows what a valid type is. +// TODO: Delete this when enableOwnerStacks ships. + function isValidElementType(type) { if (typeof type === 'string' || typeof type === 'function') { return true; @@ -703,7 +708,8 @@ function describeFunctionComponentFrame(fn) { function shouldConstruct(Component) { var prototype = Component.prototype; return !!(prototype && prototype.isReactComponent); -} +} // TODO: Delete this once the key warning no longer uses it. I.e. when enableOwnerStacks ship. + function describeUnknownElementTypeFrameInDEV(type) { @@ -937,7 +943,7 @@ function ReactElement(type, key, _ref, self, source, owner, props, debugStack, d configurable: false, enumerable: false, writable: true, - value: false + value: 0 }); // debugInfo contains Server Component debug information. Object.defineProperty(element, '_debugInfo', { @@ -1111,29 +1117,7 @@ function jsxDEV$1(type, config, maybeKey, isStaticChildren, source, self) { } } - var element = ReactElement(type, key, ref, self, source, getOwner(), props); - - if (type === REACT_FRAGMENT_TYPE) { - validateFragmentProps(element); - } - - return element; - } -} - -function getDeclarationErrorAddendum() { - { - var owner = getOwner(); - - if (owner) { - var name = getComponentNameFromType(owner.type); - - if (name) { - return '\n\nCheck the render method of `' + name + '`.'; - } - } - - return ''; + return ReactElement(type, key, ref, self, source, getOwner(), props); } } /** @@ -1146,7 +1130,6 @@ function getDeclarationErrorAddendum() { * @param {*} parentType node's parent's type. */ - function validateChildKeys(node, parentType) { { if (typeof node !== 'object' || !node) { @@ -1164,7 +1147,7 @@ function validateChildKeys(node, parentType) { } else if (isValidElement(node)) { // This element was passed in a valid location. if (node._store) { - node._store.validated = true; + node._store.validated = 1; } } else { var iteratorFn = getIteratorFn(node); @@ -1215,12 +1198,13 @@ var ownerHasKeyUseWarning = {}; */ function validateExplicitKey(element, parentType) { + { if (!element._store || element._store.validated || element.key != null) { return; } - element._store.validated = true; + element._store.validated = 1; var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType); if (ownerHasKeyUseWarning[currentComponentErrorInfo]) { @@ -1246,28 +1230,37 @@ function validateExplicitKey(element, parentType) { childOwner = " It was passed a child from " + ownerName + "."; } - setCurrentlyValidatingElement(element); + var prevGetCurrentStack = ReactSharedInternals.getCurrentStack; - error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwner); + ReactSharedInternals.getCurrentStack = function () { - setCurrentlyValidatingElement(null); - } -} + var stack = describeUnknownElementTypeFrameInDEV(element.type); // Delegate to the injected renderer-specific implementation -function setCurrentlyValidatingElement(element) { - { - if (element) { - var stack = describeUnknownElementTypeFrameInDEV(element.type); - ReactSharedInternals.setExtraStackFrame(stack); - } else { - ReactSharedInternals.setExtraStackFrame(null); - } + if (prevGetCurrentStack) { + stack += prevGetCurrentStack() || ''; + } + + return stack; + }; + + error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwner); + + ReactSharedInternals.getCurrentStack = prevGetCurrentStack; } } function getCurrentComponentErrorInfo(parentType) { { - var info = getDeclarationErrorAddendum(); + var info = ''; + var owner = getOwner(); + + if (owner) { + var name = getComponentNameFromType(owner.type); + + if (name) { + info = '\n\nCheck the render method of `' + name + '`.'; + } + } if (!info) { var parentName = getComponentNameFromType(parentType); @@ -1280,31 +1273,6 @@ function getCurrentComponentErrorInfo(parentType) { return info; } } -/** - * Given a fragment, validate that it can only be provided with fragment props - * @param {ReactElement} fragment - */ - - -function validateFragmentProps(fragment) { - // TODO: Move this to render phase instead of at element creation. - { - var keys = Object.keys(fragment.props); - - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - - if (key !== 'children' && key !== 'key') { - setCurrentlyValidatingElement(fragment); - - error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key); - - setCurrentlyValidatingElement(null); - break; - } - } - } -} var jsxDEV = jsxDEV$1 ; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/JSXRuntime-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/JSXRuntime-dev.js index ea5ba4e990e53..f78d7f4a5faf0 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/JSXRuntime-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/JSXRuntime-dev.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<> */ 'use strict'; @@ -89,11 +89,14 @@ function printWarning(level, format, args) { // update consoleWithStackDev.www.js as well. { var isErrorLogger = format === '%s\n\n%s\n' || format === '%o\n\n%s\n\n%s\n'; - var stack = ReactSharedInternals.getStackAddendum(); - if (stack !== '') { - format += '%s'; - args = args.concat([stack]); + if (ReactSharedInternals.getCurrentStack) { + var stack = ReactSharedInternals.getCurrentStack(); + + if (stack !== '') { + format += '%s'; + args = args.concat([stack]); + } } if (isErrorLogger) { @@ -305,7 +308,9 @@ function checkKeyStringCoercion(value) { } } -var REACT_CLIENT_REFERENCE$1 = Symbol.for('react.client.reference'); +var REACT_CLIENT_REFERENCE$1 = Symbol.for('react.client.reference'); // This function is deprecated. Don't use. Only the renderer knows what a valid type is. +// TODO: Delete this when enableOwnerStacks ships. + function isValidElementType(type) { if (typeof type === 'string' || typeof type === 'function') { return true; @@ -703,7 +708,8 @@ function describeFunctionComponentFrame(fn) { function shouldConstruct(Component) { var prototype = Component.prototype; return !!(prototype && prototype.isReactComponent); -} +} // TODO: Delete this once the key warning no longer uses it. I.e. when enableOwnerStacks ship. + function describeUnknownElementTypeFrameInDEV(type) { @@ -937,7 +943,7 @@ function ReactElement(type, key, _ref, self, source, owner, props, debugStack, d configurable: false, enumerable: false, writable: true, - value: false + value: 0 }); // debugInfo contains Server Component debug information. Object.defineProperty(element, '_debugInfo', { @@ -1135,29 +1141,7 @@ function jsxDEV(type, config, maybeKey, isStaticChildren, source, self) { } } - var element = ReactElement(type, key, ref, self, source, getOwner(), props); - - if (type === REACT_FRAGMENT_TYPE) { - validateFragmentProps(element); - } - - return element; - } -} - -function getDeclarationErrorAddendum() { - { - var owner = getOwner(); - - if (owner) { - var name = getComponentNameFromType(owner.type); - - if (name) { - return '\n\nCheck the render method of `' + name + '`.'; - } - } - - return ''; + return ReactElement(type, key, ref, self, source, getOwner(), props); } } /** @@ -1170,7 +1154,6 @@ function getDeclarationErrorAddendum() { * @param {*} parentType node's parent's type. */ - function validateChildKeys(node, parentType) { { if (typeof node !== 'object' || !node) { @@ -1188,7 +1171,7 @@ function validateChildKeys(node, parentType) { } else if (isValidElement(node)) { // This element was passed in a valid location. if (node._store) { - node._store.validated = true; + node._store.validated = 1; } } else { var iteratorFn = getIteratorFn(node); @@ -1239,12 +1222,13 @@ var ownerHasKeyUseWarning = {}; */ function validateExplicitKey(element, parentType) { + { if (!element._store || element._store.validated || element.key != null) { return; } - element._store.validated = true; + element._store.validated = 1; var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType); if (ownerHasKeyUseWarning[currentComponentErrorInfo]) { @@ -1270,28 +1254,37 @@ function validateExplicitKey(element, parentType) { childOwner = " It was passed a child from " + ownerName + "."; } - setCurrentlyValidatingElement(element); + var prevGetCurrentStack = ReactSharedInternals.getCurrentStack; - error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwner); + ReactSharedInternals.getCurrentStack = function () { - setCurrentlyValidatingElement(null); - } -} + var stack = describeUnknownElementTypeFrameInDEV(element.type); // Delegate to the injected renderer-specific implementation -function setCurrentlyValidatingElement(element) { - { - if (element) { - var stack = describeUnknownElementTypeFrameInDEV(element.type); - ReactSharedInternals.setExtraStackFrame(stack); - } else { - ReactSharedInternals.setExtraStackFrame(null); - } + if (prevGetCurrentStack) { + stack += prevGetCurrentStack() || ''; + } + + return stack; + }; + + error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwner); + + ReactSharedInternals.getCurrentStack = prevGetCurrentStack; } } function getCurrentComponentErrorInfo(parentType) { { - var info = getDeclarationErrorAddendum(); + var info = ''; + var owner = getOwner(); + + if (owner) { + var name = getComponentNameFromType(owner.type); + + if (name) { + info = '\n\nCheck the render method of `' + name + '`.'; + } + } if (!info) { var parentName = getComponentNameFromType(parentType); @@ -1304,31 +1297,6 @@ function getCurrentComponentErrorInfo(parentType) { return info; } } -/** - * Given a fragment, validate that it can only be provided with fragment props - * @param {ReactElement} fragment - */ - - -function validateFragmentProps(fragment) { - // TODO: Move this to render phase instead of at element creation. - { - var keys = Object.keys(fragment.props); - - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - - if (key !== 'children' && key !== 'key') { - setCurrentlyValidatingElement(fragment); - - error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key); - - setCurrentlyValidatingElement(null); - break; - } - } - } -} var jsx = jsxProdSignatureRunningInDevWithDynamicChildren ; // we may want to special case jsxs internally to take advantage of static children. // for now we can ship identical prod functions diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js index cec1a9256a580..d2cd3036d1205 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<99e34fed5db832c23f4f082b7bcba4d2>> + * @generated SignedSource<> */ 'use strict'; @@ -24,7 +24,7 @@ if ( } var dynamicFlagsUntyped = require('ReactNativeInternalFeatureFlags'); -var ReactVersion = '19.0.0-rc-6e8d1fca'; +var ReactVersion = '19.0.0-rc-03d16137'; // Re-export dynamic flags from the internal module. var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on @@ -93,32 +93,9 @@ var ReactSharedInternals = { ReactSharedInternals.isBatchingLegacy = false; ReactSharedInternals.didScheduleLegacyUpdate = false; ReactSharedInternals.didUsePromise = false; - ReactSharedInternals.thrownErrors = []; - var currentExtraStackFrame = null; - - ReactSharedInternals.setExtraStackFrame = function (stack) { - currentExtraStackFrame = stack; - }; // Stack implementation injected by the current renderer. - + ReactSharedInternals.thrownErrors = []; // Stack implementation injected by the current renderer. ReactSharedInternals.getCurrentStack = null; - - ReactSharedInternals.getStackAddendum = function () { - var stack = ''; // Add an extra top frame while an element is being validated - - if (currentExtraStackFrame) { - stack += currentExtraStackFrame; - } // Delegate to the injected renderer-specific implementation - - - var impl = ReactSharedInternals.getCurrentStack; - - if (impl) { - stack += impl() || ''; - } - - return stack; - }; } // by calls to these methods by a Babel plugin. @@ -154,11 +131,14 @@ function printWarning(level, format, args) { // update consoleWithStackDev.www.js as well. { var isErrorLogger = format === '%s\n\n%s\n' || format === '%o\n\n%s\n\n%s\n'; - var stack = ReactSharedInternals.getStackAddendum(); - if (stack !== '') { - format += '%s'; - args = args.concat([stack]); + if (ReactSharedInternals.getCurrentStack) { + var stack = ReactSharedInternals.getCurrentStack(); + + if (stack !== '') { + format += '%s'; + args = args.concat([stack]); + } } if (isErrorLogger) { @@ -600,7 +580,9 @@ function getComponentNameFromType(type) { // $FlowFixMe[method-unbinding] var hasOwnProperty = Object.prototype.hasOwnProperty; -var REACT_CLIENT_REFERENCE$1 = Symbol.for('react.client.reference'); +var REACT_CLIENT_REFERENCE$1 = Symbol.for('react.client.reference'); // This function is deprecated. Don't use. Only the renderer knows what a valid type is. +// TODO: Delete this when enableOwnerStacks ships. + function isValidElementType(type) { if (typeof type === 'string' || typeof type === 'function') { return true; @@ -992,7 +974,8 @@ function describeFunctionComponentFrame(fn) { function shouldConstruct(Component) { var prototype = Component.prototype; return !!(prototype && prototype.isReactComponent); -} +} // TODO: Delete this once the key warning no longer uses it. I.e. when enableOwnerStacks ship. + function describeUnknownElementTypeFrameInDEV(type) { @@ -1227,7 +1210,7 @@ function ReactElement(type, key, _ref, self, source, owner, props, debugStack, d configurable: false, enumerable: false, writable: true, - value: false + value: 0 }); // debugInfo contains Server Component debug information. Object.defineProperty(element, '_debugInfo', { @@ -1425,13 +1408,7 @@ function jsxDEV$1(type, config, maybeKey, isStaticChildren, source, self) { } } - var element = ReactElement(type, key, ref, self, source, getOwner(), props); - - if (type === REACT_FRAGMENT_TYPE) { - validateFragmentProps(element); - } - - return element; + return ReactElement(type, key, ref, self, source, getOwner(), props); } } /** @@ -1442,6 +1419,11 @@ function jsxDEV$1(type, config, maybeKey, isStaticChildren, source, self) { function createElement(type, config, children) { { if (!isValidElementType(type)) { + // This is just an optimistic check that provides a better stack trace before + // owner stacks. It's really up to the renderer if it's a valid element type. + // When owner stacks are enabled, we instead warn in the renderer and it'll + // have the stack trace of the JSX element anyway. + // // This is an invalid element type. // // We warn in this case but don't throw. We expect the element creation to @@ -1568,13 +1550,7 @@ function createElement(type, config, children) { } } - var element = ReactElement(type, key, ref, undefined, undefined, getOwner(), props); - - if (type === REACT_FRAGMENT_TYPE) { - validateFragmentProps(element); - } - - return element; + 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 @@ -1668,22 +1644,6 @@ function cloneElement(element, config, children) { return clonedElement; } - -function getDeclarationErrorAddendum() { - { - var owner = getOwner(); - - if (owner) { - var name = getComponentNameFromType(owner.type); - - if (name) { - return '\n\nCheck the render method of `' + name + '`.'; - } - } - - return ''; - } -} /** * Ensure that every element either is passed in a static location, in an * array with an explicit keys property defined, or in an object literal @@ -1694,7 +1654,6 @@ function getDeclarationErrorAddendum() { * @param {*} parentType node's parent's type. */ - function validateChildKeys(node, parentType) { { if (typeof node !== 'object' || !node) { @@ -1712,7 +1671,7 @@ function validateChildKeys(node, parentType) { } else if (isValidElement(node)) { // This element was passed in a valid location. if (node._store) { - node._store.validated = true; + node._store.validated = 1; } } else { var iteratorFn = getIteratorFn(node); @@ -1763,12 +1722,13 @@ var ownerHasKeyUseWarning = {}; */ function validateExplicitKey(element, parentType) { + { if (!element._store || element._store.validated || element.key != null) { return; } - element._store.validated = true; + element._store.validated = 1; var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType); if (ownerHasKeyUseWarning[currentComponentErrorInfo]) { @@ -1794,28 +1754,37 @@ function validateExplicitKey(element, parentType) { childOwner = " It was passed a child from " + ownerName + "."; } - setCurrentlyValidatingElement(element); + var prevGetCurrentStack = ReactSharedInternals.getCurrentStack; - error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwner); + ReactSharedInternals.getCurrentStack = function () { - setCurrentlyValidatingElement(null); - } -} + var stack = describeUnknownElementTypeFrameInDEV(element.type); // Delegate to the injected renderer-specific implementation -function setCurrentlyValidatingElement(element) { - { - if (element) { - var stack = describeUnknownElementTypeFrameInDEV(element.type); - ReactSharedInternals.setExtraStackFrame(stack); - } else { - ReactSharedInternals.setExtraStackFrame(null); - } + if (prevGetCurrentStack) { + stack += prevGetCurrentStack() || ''; + } + + return stack; + }; + + error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwner); + + ReactSharedInternals.getCurrentStack = prevGetCurrentStack; } } function getCurrentComponentErrorInfo(parentType) { { - var info = getDeclarationErrorAddendum(); + var info = ''; + var owner = getOwner(); + + if (owner) { + var name = getComponentNameFromType(owner.type); + + if (name) { + info = '\n\nCheck the render method of `' + name + '`.'; + } + } if (!info) { var parentName = getComponentNameFromType(parentType); @@ -1828,31 +1797,6 @@ function getCurrentComponentErrorInfo(parentType) { return info; } } -/** - * Given a fragment, validate that it can only be provided with fragment props - * @param {ReactElement} fragment - */ - - -function validateFragmentProps(fragment) { - // TODO: Move this to render phase instead of at element creation. - { - var keys = Object.keys(fragment.props); - - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - - if (key !== 'children' && key !== 'key') { - setCurrentlyValidatingElement(fragment); - - error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key); - - setCurrentlyValidatingElement(null); - break; - } - } - } -} var SEPARATOR = '.'; var SUBSEPARATOR = ':'; @@ -2036,17 +1980,32 @@ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) { // The `if` statement here prevents auto-disabling of the safe // coercion ESLint rule, so we must manually disable it below. // $FlowFixMe[incompatible-type] Flow incorrectly thinks React.Portal doesn't have a key - if (mappedChild.key && (!_child || _child.key !== mappedChild.key)) { - checkKeyStringCoercion(mappedChild.key); + if (mappedChild.key != null) { + if (!_child || _child.key !== mappedChild.key) { + checkKeyStringCoercion(mappedChild.key); + } } } - mappedChild = cloneAndReplaceKey(mappedChild, // Keep both the (mapped) and old keys if they differ, just as + var newChild = cloneAndReplaceKey(mappedChild, // Keep both the (mapped) and old keys if they differ, just as // traverseAllChildren used to do for objects as children escapedPrefix + ( // $FlowFixMe[incompatible-type] Flow incorrectly thinks React.Portal doesn't have a key - mappedChild.key && (!_child || _child.key !== mappedChild.key) ? escapeUserProvidedKey( // $FlowFixMe[unsafe-addition] + mappedChild.key != null && (!_child || _child.key !== mappedChild.key) ? escapeUserProvidedKey( // $FlowFixMe[unsafe-addition] '' + mappedChild.key // eslint-disable-line react-internal/safe-string-coercion ) + '/' : '') + childKey); + + { + if (nameSoFar !== '' && mappedChild.key == null) { + // We need to validate that this child should have had a key before assigning it one. + if (!newChild._store.validated) { + // We mark this child as having failed validation but we let the actual renderer + // print the warning later. + newChild._store.validated = 2; + } + } + } + + mappedChild = newChild; } array.push(mappedChild); diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-prod.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-prod.js index bdcd3bad78358..70e26af075617 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-prod.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-prod.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<351b89bf44a598ef0b145129629686f1>> */ "use strict"; @@ -234,7 +234,8 @@ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) { (callback = cloneAndReplaceKey( callback, escapedPrefix + - (!callback.key || (children && children.key === callback.key) + (null == callback.key || + (children && children.key === callback.key) ? "" : ("" + callback.key).replace( userProvidedKeyEscapeRegex, @@ -604,4 +605,4 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactSharedInternals.H.useTransition(); }; -exports.version = "19.0.0-rc-d03b5f88"; +exports.version = "19.0.0-rc-f9855a0e"; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-profiling.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-profiling.js index 9fc2f71c5155a..e589a0cca8e46 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-profiling.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-profiling.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<6b31810711d4bd421bdf65bafdf70c01>> + * @generated SignedSource<> */ "use strict"; @@ -238,7 +238,8 @@ function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) { (callback = cloneAndReplaceKey( callback, escapedPrefix + - (!callback.key || (children && children.key === callback.key) + (null == callback.key || + (children && children.key === callback.key) ? "" : ("" + callback.key).replace( userProvidedKeyEscapeRegex, @@ -608,7 +609,7 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactSharedInternals.H.useTransition(); }; -exports.version = "19.0.0-rc-8d1b9547"; +exports.version = "19.0.0-rc-680d5437"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION index ebe1927dab20f..d83a118da1b43 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION @@ -1 +1 @@ -2e540e22b2b4038a278b2875306976b016fb31a9 +84239da896fd7395a667ab1e7ef1ef338a32de8f diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js index d785347a9cf86..854de0d5a6070 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<8e6cf83f111cde978e0cd11aa9ce59ec>> + * @generated SignedSource<> */ 'use strict'; @@ -69,11 +69,14 @@ function printWarning(level, format, args) { // update consoleWithStackDev.www.js as well. { var isErrorLogger = format === '%s\n\n%s\n' || format === '%o\n\n%s\n\n%s\n'; - var stack = ReactSharedInternals.getStackAddendum(); - if (stack !== '') { - format += '%s'; - args = args.concat([stack]); + if (ReactSharedInternals.getCurrentStack) { + var stack = ReactSharedInternals.getCurrentStack(); + + if (stack !== '') { + format += '%s'; + args = args.concat([stack]); + } } if (isErrorLogger) { @@ -8366,7 +8369,7 @@ var warnForMissingKey = function (child, returnFiber) {}; return; } - if (!child._store || child._store.validated || child.key != null) { + if (!child._store || (child._store.validated || child.key != null) && child._store.validated !== 2) { return; } @@ -8375,17 +8378,96 @@ var warnForMissingKey = function (child, returnFiber) {}; } // $FlowFixMe[cannot-write] unable to narrow type from mixed to writable object - child._store.validated = true; - var componentName = getComponentNameFromFiber(returnFiber) || 'Component'; + child._store.validated = 1; + var componentName = getComponentNameFromFiber(returnFiber); + var componentKey = componentName || 'null'; - if (ownerHasKeyUseWarning[componentName]) { + if (ownerHasKeyUseWarning[componentKey]) { return; } - ownerHasKeyUseWarning[componentName] = true; + ownerHasKeyUseWarning[componentKey] = true; + var childOwner = child._owner; + var parentOwner = returnFiber._debugOwner; + var currentComponentErrorInfo = ''; + + if (parentOwner && typeof parentOwner.tag === 'number') { + var name = getComponentNameFromFiber(parentOwner); + + if (name) { + currentComponentErrorInfo = '\n\nCheck the render method of `' + name + '`.'; + } + } + + if (!currentComponentErrorInfo) { + if (componentName) { + currentComponentErrorInfo = "\n\nCheck the top-level render call using <" + componentName + ">."; + } + } // Usually the current owner is the offender, but if it accepts children as a + // property, it may be the creator of the child that's responsible for + // assigning it a key. + + + var childOwnerAppendix = ''; + + if (childOwner != null && parentOwner !== childOwner) { + var ownerName = null; + + if (typeof childOwner.tag === 'number') { + ownerName = getComponentNameFromFiber(childOwner); + } else if (typeof childOwner.name === 'string') { + ownerName = childOwner.name; + } + + if (ownerName) { + // Give the component that originally created this child. + childOwnerAppendix = " It was passed a child from " + ownerName + "."; + } + } // We create a fake Fiber for the child to log the stack trace from. + // TODO: Refactor the warnForMissingKey calls to happen after fiber creation + // so that we can get access to the fiber that will eventually be created. + // That way the log can show up associated with the right instance in DevTools. + + + var fiber = createFiberFromElement(child, returnFiber.mode, 0); + fiber.return = returnFiber; + var prevDebugFiber = getCurrentFiber(); + setCurrentFiber(fiber); + + error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwnerAppendix); - error('Each child in a list should have a unique ' + '"key" prop. See https://react.dev/link/warning-keys for ' + 'more information.'); + setCurrentFiber(prevDebugFiber); }; +} // Given a fragment, validate that it can only be provided with fragment props +// We do this here instead of BeginWork because the Fragment fiber doesn't have +// the whole props object, only the children and is shared with arrays. + + +function validateFragmentProps(element, fiber, returnFiber) { + { + var keys = Object.keys(element.props); + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + + if (key !== 'children' && key !== 'key') { + if (fiber === null) { + // For unkeyed root fragments there's no Fiber. We create a fake one just for + // error stack handling. + fiber = createFiberFromElement(element, returnFiber.mode, 0); + fiber.return = returnFiber; + } + + var prevDebugFiber = getCurrentFiber(); + setCurrentFiber(fiber); + + error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key); + + setCurrentFiber(prevDebugFiber); + break; + } + } + } } function unwrapThenable(thenable) { @@ -8606,7 +8688,9 @@ function createChildReconciler(shouldTrackSideEffects) { var elementType = element.type; if (elementType === REACT_FRAGMENT_TYPE) { - return updateFragment(returnFiber, current, element.props.children, lanes, element.key, debugInfo); + var updated = updateFragment(returnFiber, current, element.props.children, lanes, element.key, debugInfo); + validateFragmentProps(element, updated, returnFiber); + return updated; } if (current !== null) { @@ -9350,6 +9434,7 @@ function createChildReconciler(shouldTrackSideEffects) { existing._debugInfo = debugInfo; } + validateFragmentProps(element, existing, returnFiber); return existing; } } else { @@ -9393,6 +9478,7 @@ function createChildReconciler(shouldTrackSideEffects) { created._debugInfo = debugInfo; } + validateFragmentProps(element, created, returnFiber); return created; } else { var _created4 = createFiberFromElement(element, returnFiber.mode, lanes); @@ -9455,6 +9541,7 @@ function createChildReconciler(shouldTrackSideEffects) { var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null; if (isUnkeyedTopLevelFragment) { + validateFragmentProps(newChild, null, returnFiber); newChild = newChild.props.children; } // Handle object types @@ -25852,10 +25939,22 @@ key, pendingProps, owner, mode, lanes) { } var info = ''; + var typeString; { if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { - info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and " + 'named imports.'; + info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and named imports."; + } + + if (type === null) { + typeString = 'null'; + } else if (isArray(type)) { + typeString = 'array'; + } else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) { + typeString = "<" + (getComponentNameFromType(type.type) || 'Unknown') + " />"; + info = ' Did you accidentally export a JSX literal instead of a component?'; + } else { + typeString = typeof type; } var ownerName = owner ? getComponentNameFromOwner(owner) : null; @@ -25865,7 +25964,7 @@ key, pendingProps, owner, mode, lanes) { } } - throw new Error('Element type is invalid: expected a string (for built-in ' + 'components) or a class/function (for composite components) ' + ("but got: " + (type == null ? type : typeof type) + "." + info)); + throw new Error('Element type is invalid: expected a string (for built-in ' + 'components) or a class/function (for composite components) ' + ("but got: " + typeString + "." + info)); } } } @@ -26083,7 +26182,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-1ca22f1f'; +var ReactVersion = '19.0.0-rc-044bb948'; /* * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 2e631936967ba..dfc95f6a6c141 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<1d2b130328f4bb108e9de82ba65c62c7>> + * @generated SignedSource<> */ "use strict"; @@ -10184,7 +10184,7 @@ function createFiberFromTypeAndProps( } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - ((null == type ? type : typeof type) + ".") + ((null === type ? "null" : typeof type) + ".") ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -10558,7 +10558,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1119 = { findFiberByHostInstance: getInstanceFromNode, bundleType: 0, - version: "19.0.0-rc-727abc63", + version: "19.0.0-rc-055b7648", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10601,7 +10601,7 @@ var internals$jscomp$inline_1349 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-727abc63" + reconcilerVersion: "19.0.0-rc-055b7648" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1350 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index f7a48b05482ac..8d4c5104a8d90 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<86492ff1a75d58ad80afad8ec9246a92>> + * @generated SignedSource<<0b75a31fef7d2e5730b330ff31d90222>> */ "use strict"; @@ -10882,7 +10882,7 @@ function createFiberFromTypeAndProps( } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - ((null == type ? type : typeof type) + ".") + ((null === type ? "null" : typeof type) + ".") ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -11263,7 +11263,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1199 = { findFiberByHostInstance: getInstanceFromNode, bundleType: 0, - version: "19.0.0-rc-0c0ae0e7", + version: "19.0.0-rc-8e11d2fc", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -11319,7 +11319,7 @@ var roots = new Map(), scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-0c0ae0e7" + reconcilerVersion: "19.0.0-rc-8e11d2fc" }); exports.createPortal = function (children, containerTag) { return createPortal$1( diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index 7959954e38057..46640a50c8320 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<1621d1d30eec467749cd3a95ce1c9b2f>> + * @generated SignedSource<> */ 'use strict'; @@ -69,11 +69,14 @@ function printWarning(level, format, args) { // update consoleWithStackDev.www.js as well. { var isErrorLogger = format === '%s\n\n%s\n' || format === '%o\n\n%s\n\n%s\n'; - var stack = ReactSharedInternals.getStackAddendum(); - if (stack !== '') { - format += '%s'; - args = args.concat([stack]); + if (ReactSharedInternals.getCurrentStack) { + var stack = ReactSharedInternals.getCurrentStack(); + + if (stack !== '') { + format += '%s'; + args = args.concat([stack]); + } } if (isErrorLogger) { @@ -8543,7 +8546,7 @@ var warnForMissingKey = function (child, returnFiber) {}; return; } - if (!child._store || child._store.validated || child.key != null) { + if (!child._store || (child._store.validated || child.key != null) && child._store.validated !== 2) { return; } @@ -8552,17 +8555,96 @@ var warnForMissingKey = function (child, returnFiber) {}; } // $FlowFixMe[cannot-write] unable to narrow type from mixed to writable object - child._store.validated = true; - var componentName = getComponentNameFromFiber(returnFiber) || 'Component'; + child._store.validated = 1; + var componentName = getComponentNameFromFiber(returnFiber); + var componentKey = componentName || 'null'; - if (ownerHasKeyUseWarning[componentName]) { + if (ownerHasKeyUseWarning[componentKey]) { return; } - ownerHasKeyUseWarning[componentName] = true; + ownerHasKeyUseWarning[componentKey] = true; + var childOwner = child._owner; + var parentOwner = returnFiber._debugOwner; + var currentComponentErrorInfo = ''; + + if (parentOwner && typeof parentOwner.tag === 'number') { + var name = getComponentNameFromFiber(parentOwner); + + if (name) { + currentComponentErrorInfo = '\n\nCheck the render method of `' + name + '`.'; + } + } + + if (!currentComponentErrorInfo) { + if (componentName) { + currentComponentErrorInfo = "\n\nCheck the top-level render call using <" + componentName + ">."; + } + } // Usually the current owner is the offender, but if it accepts children as a + // property, it may be the creator of the child that's responsible for + // assigning it a key. + + + var childOwnerAppendix = ''; + + if (childOwner != null && parentOwner !== childOwner) { + var ownerName = null; + + if (typeof childOwner.tag === 'number') { + ownerName = getComponentNameFromFiber(childOwner); + } else if (typeof childOwner.name === 'string') { + ownerName = childOwner.name; + } + + if (ownerName) { + // Give the component that originally created this child. + childOwnerAppendix = " It was passed a child from " + ownerName + "."; + } + } // We create a fake Fiber for the child to log the stack trace from. + // TODO: Refactor the warnForMissingKey calls to happen after fiber creation + // so that we can get access to the fiber that will eventually be created. + // That way the log can show up associated with the right instance in DevTools. + + + var fiber = createFiberFromElement(child, returnFiber.mode, 0); + fiber.return = returnFiber; + var prevDebugFiber = getCurrentFiber(); + setCurrentFiber(fiber); + + error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwnerAppendix); - error('Each child in a list should have a unique ' + '"key" prop. See https://react.dev/link/warning-keys for ' + 'more information.'); + setCurrentFiber(prevDebugFiber); }; +} // Given a fragment, validate that it can only be provided with fragment props +// We do this here instead of BeginWork because the Fragment fiber doesn't have +// the whole props object, only the children and is shared with arrays. + + +function validateFragmentProps(element, fiber, returnFiber) { + { + var keys = Object.keys(element.props); + + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + + if (key !== 'children' && key !== 'key') { + if (fiber === null) { + // For unkeyed root fragments there's no Fiber. We create a fake one just for + // error stack handling. + fiber = createFiberFromElement(element, returnFiber.mode, 0); + fiber.return = returnFiber; + } + + var prevDebugFiber = getCurrentFiber(); + setCurrentFiber(fiber); + + error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key); + + setCurrentFiber(prevDebugFiber); + break; + } + } + } } function unwrapThenable(thenable) { @@ -8783,7 +8865,9 @@ function createChildReconciler(shouldTrackSideEffects) { var elementType = element.type; if (elementType === REACT_FRAGMENT_TYPE) { - return updateFragment(returnFiber, current, element.props.children, lanes, element.key, debugInfo); + var updated = updateFragment(returnFiber, current, element.props.children, lanes, element.key, debugInfo); + validateFragmentProps(element, updated, returnFiber); + return updated; } if (current !== null) { @@ -9527,6 +9611,7 @@ function createChildReconciler(shouldTrackSideEffects) { existing._debugInfo = debugInfo; } + validateFragmentProps(element, existing, returnFiber); return existing; } } else { @@ -9570,6 +9655,7 @@ function createChildReconciler(shouldTrackSideEffects) { created._debugInfo = debugInfo; } + validateFragmentProps(element, created, returnFiber); return created; } else { var _created4 = createFiberFromElement(element, returnFiber.mode, lanes); @@ -9632,6 +9718,7 @@ function createChildReconciler(shouldTrackSideEffects) { var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null; if (isUnkeyedTopLevelFragment) { + validateFragmentProps(newChild, null, returnFiber); newChild = newChild.props.children; } // Handle object types @@ -26202,10 +26289,22 @@ key, pendingProps, owner, mode, lanes) { } var info = ''; + var typeString; { if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { - info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and " + 'named imports.'; + info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and named imports."; + } + + if (type === null) { + typeString = 'null'; + } else if (isArray(type)) { + typeString = 'array'; + } else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) { + typeString = "<" + (getComponentNameFromType(type.type) || 'Unknown') + " />"; + info = ' Did you accidentally export a JSX literal instead of a component?'; + } else { + typeString = typeof type; } var ownerName = owner ? getComponentNameFromOwner(owner) : null; @@ -26215,7 +26314,7 @@ key, pendingProps, owner, mode, lanes) { } } - throw new Error('Element type is invalid: expected a string (for built-in ' + 'components) or a class/function (for composite components) ' + ("but got: " + (type == null ? type : typeof type) + "." + info)); + throw new Error('Element type is invalid: expected a string (for built-in ' + 'components) or a class/function (for composite components) ' + ("but got: " + typeString + "." + info)); } } } @@ -26433,7 +26532,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-e5ef3855'; +var ReactVersion = '19.0.0-rc-e14bbf66'; /* * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index fb4d0929f9a1e..27a71f2103a27 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<3847450e7210fcecd6638e86d2f3123b>> */ "use strict"; @@ -10366,7 +10366,7 @@ function createFiberFromTypeAndProps( } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - ((null == type ? type : typeof type) + ".") + ((null === type ? "null" : typeof type) + ".") ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -10747,7 +10747,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1187 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "19.0.0-rc-56edf199", + version: "19.0.0-rc-a21ccfc5", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10790,7 +10790,7 @@ var internals$jscomp$inline_1434 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-56edf199" + reconcilerVersion: "19.0.0-rc-a21ccfc5" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1435 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index 1e17c3f0e45b7..d7d6787cd8369 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<97a595a3f85a65f2977dfd3658e3254b>> + * @generated SignedSource<> */ "use strict"; @@ -11065,7 +11065,7 @@ function createFiberFromTypeAndProps( } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + - ((null == type ? type : typeof type) + ".") + ((null === type ? "null" : typeof type) + ".") ); } key = createFiber(fiberTag, pendingProps, key, mode); @@ -11453,7 +11453,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1267 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "19.0.0-rc-18d64a29", + version: "19.0.0-rc-d95f3bff", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -11509,7 +11509,7 @@ var roots = new Map(), scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-18d64a29" + reconcilerVersion: "19.0.0-rc-d95f3bff" }); exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { computeComponentStackForErrorReporting: function (reactTag) {