From 3ff23f923448d83528f5f09b8032bf3a56ff3de6 Mon Sep 17 00:00:00 2001 From: sebmarkbage Date: Mon, 19 Feb 2024 17:41:20 +0000 Subject: [PATCH] [Flight] Better error message if you pass a function as a child to a client component (#28367) Similar to #28362 but if you pass it to a client component. DiffTrain build for [2e84e1629924e6cb278638305fa92040f6ef6eb5](https://github.com/facebook/react/commit/2e84e1629924e6cb278638305fa92040f6ef6eb5) --- compiled/facebook-www/REVISION | 2 +- compiled/facebook-www/React-prod.modern.js | 2 +- .../ReactDOMServer-dev.classic.js | 17 ++++++---- .../facebook-www/ReactDOMServer-dev.modern.js | 17 ++++++---- .../ReactDOMServerStreaming-dev.modern.js | 15 +++++---- .../ReactDOMTesting-prod.modern.js | 6 ++-- .../ReactFlightDOMServer-dev.modern.js | 33 +++++++++++++++---- .../ReactFlightDOMServer-prod.modern.js | 16 +++++---- .../ReactTestRenderer-dev.modern.js | 2 +- 9 files changed, 71 insertions(+), 39 deletions(-) diff --git a/compiled/facebook-www/REVISION b/compiled/facebook-www/REVISION index 60be7417650c6..5d5d138efd3b1 100644 --- a/compiled/facebook-www/REVISION +++ b/compiled/facebook-www/REVISION @@ -1 +1 @@ -65a0e2b25ec4642f83c32d7599b5252c3955a60b +2e84e1629924e6cb278638305fa92040f6ef6eb5 diff --git a/compiled/facebook-www/React-prod.modern.js b/compiled/facebook-www/React-prod.modern.js index 202eacea293bb..188690a4d83f5 100644 --- a/compiled/facebook-www/React-prod.modern.js +++ b/compiled/facebook-www/React-prod.modern.js @@ -610,4 +610,4 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactCurrentDispatcher.current.useTransition(); }; -exports.version = "18.3.0-www-modern-f4161761"; +exports.version = "18.3.0-www-modern-cf1f133e"; diff --git a/compiled/facebook-www/ReactDOMServer-dev.classic.js b/compiled/facebook-www/ReactDOMServer-dev.classic.js index e5efb83c4f354..2ed26d8b3f1c0 100644 --- a/compiled/facebook-www/ReactDOMServer-dev.classic.js +++ b/compiled/facebook-www/ReactDOMServer-dev.classic.js @@ -19,7 +19,7 @@ if (__DEV__) { var React = require("react"); var ReactDOM = require("react-dom"); - var ReactVersion = "18.3.0-www-classic-a730f95d"; + var ReactVersion = "18.3.0-www-classic-cd3b8d66"; // This refers to a WWW module. var warningWWW = require("warning"); @@ -184,12 +184,15 @@ if (__DEV__) { return name; } - case "function": + case "function": { if (value.$$typeof === CLIENT_REFERENCE_TAG) { return describeClientReference(); } - return "function"; + var _name = value.displayName || value.name; + + return _name ? "function " + _name : "function"; + } default: // eslint-disable-next-line react-internal/safe-string-coercion @@ -380,9 +383,9 @@ if (__DEV__) { str += ", "; } - var _name = _names[_i3]; - str += describeKeyForErrorMessage(_name) + ": "; - var _value3 = _object[_name]; + var _name2 = _names[_i3]; + str += describeKeyForErrorMessage(_name2) + ": "; + var _value3 = _object[_name2]; var _substr3 = void 0; @@ -392,7 +395,7 @@ if (__DEV__) { _substr3 = describeValueForErrorMessage(_value3); } - if (_name === expandedName) { + if (_name2 === expandedName) { start = str.length; length = _substr3.length; str += _substr3; diff --git a/compiled/facebook-www/ReactDOMServer-dev.modern.js b/compiled/facebook-www/ReactDOMServer-dev.modern.js index f40e1420c80e2..df95d288e563e 100644 --- a/compiled/facebook-www/ReactDOMServer-dev.modern.js +++ b/compiled/facebook-www/ReactDOMServer-dev.modern.js @@ -19,7 +19,7 @@ if (__DEV__) { var React = require("react"); var ReactDOM = require("react-dom"); - var ReactVersion = "18.3.0-www-modern-2b72b29d"; + var ReactVersion = "18.3.0-www-modern-06e02b7d"; // This refers to a WWW module. var warningWWW = require("warning"); @@ -184,12 +184,15 @@ if (__DEV__) { return name; } - case "function": + case "function": { if (value.$$typeof === CLIENT_REFERENCE_TAG) { return describeClientReference(); } - return "function"; + var _name = value.displayName || value.name; + + return _name ? "function " + _name : "function"; + } default: // eslint-disable-next-line react-internal/safe-string-coercion @@ -380,9 +383,9 @@ if (__DEV__) { str += ", "; } - var _name = _names[_i3]; - str += describeKeyForErrorMessage(_name) + ": "; - var _value3 = _object[_name]; + var _name2 = _names[_i3]; + str += describeKeyForErrorMessage(_name2) + ": "; + var _value3 = _object[_name2]; var _substr3 = void 0; @@ -392,7 +395,7 @@ if (__DEV__) { _substr3 = describeValueForErrorMessage(_value3); } - if (_name === expandedName) { + if (_name2 === expandedName) { start = str.length; length = _substr3.length; str += _substr3; diff --git a/compiled/facebook-www/ReactDOMServerStreaming-dev.modern.js b/compiled/facebook-www/ReactDOMServerStreaming-dev.modern.js index ce6d85f9b6d3f..478d7a1f19449 100644 --- a/compiled/facebook-www/ReactDOMServerStreaming-dev.modern.js +++ b/compiled/facebook-www/ReactDOMServerStreaming-dev.modern.js @@ -182,12 +182,15 @@ if (__DEV__) { return name; } - case "function": + case "function": { if (value.$$typeof === CLIENT_REFERENCE_TAG) { return describeClientReference(); } - return "function"; + var _name = value.displayName || value.name; + + return _name ? "function " + _name : "function"; + } default: // eslint-disable-next-line react-internal/safe-string-coercion @@ -378,9 +381,9 @@ if (__DEV__) { str += ", "; } - var _name = _names[_i3]; - str += describeKeyForErrorMessage(_name) + ": "; - var _value3 = _object[_name]; + var _name2 = _names[_i3]; + str += describeKeyForErrorMessage(_name2) + ": "; + var _value3 = _object[_name2]; var _substr3 = void 0; @@ -390,7 +393,7 @@ if (__DEV__) { _substr3 = describeValueForErrorMessage(_value3); } - if (_name === expandedName) { + if (_name2 === expandedName) { start = str.length; length = _substr3.length; str += _substr3; diff --git a/compiled/facebook-www/ReactDOMTesting-prod.modern.js b/compiled/facebook-www/ReactDOMTesting-prod.modern.js index b0f2f6088ec91..c2fcff170b3ac 100644 --- a/compiled/facebook-www/ReactDOMTesting-prod.modern.js +++ b/compiled/facebook-www/ReactDOMTesting-prod.modern.js @@ -17085,7 +17085,7 @@ Internals.Events = [ var devToolsConfig$jscomp$inline_1783 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "18.3.0-www-modern-448aa5e1", + version: "18.3.0-www-modern-90e18ae7", rendererPackageName: "react-dom" }; var internals$jscomp$inline_2154 = { @@ -17116,7 +17116,7 @@ var internals$jscomp$inline_2154 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-www-modern-448aa5e1" + reconcilerVersion: "18.3.0-www-modern-90e18ae7" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2155 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -17537,4 +17537,4 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactCurrentDispatcher$2.current.useHostTransitionStatus(); }; -exports.version = "18.3.0-www-modern-448aa5e1"; +exports.version = "18.3.0-www-modern-90e18ae7"; diff --git a/compiled/facebook-www/ReactFlightDOMServer-dev.modern.js b/compiled/facebook-www/ReactFlightDOMServer-dev.modern.js index f62d54b8e72a9..b7f5733bc1faa 100644 --- a/compiled/facebook-www/ReactFlightDOMServer-dev.modern.js +++ b/compiled/facebook-www/ReactFlightDOMServer-dev.modern.js @@ -842,12 +842,15 @@ if (__DEV__) { return name; } - case "function": + case "function": { if (value.$$typeof === CLIENT_REFERENCE_TAG) { return describeClientReference(); } - return "function"; + var _name = value.displayName || value.name; + + return _name ? "function " + _name : "function"; + } default: // eslint-disable-next-line react-internal/safe-string-coercion @@ -1038,9 +1041,9 @@ if (__DEV__) { str += ", "; } - var _name = _names[_i3]; - str += describeKeyForErrorMessage(_name) + ": "; - var _value3 = _object[_name]; + var _name2 = _names[_i3]; + str += describeKeyForErrorMessage(_name2) + ": "; + var _value3 = _object[_name2]; var _substr3 = void 0; @@ -1050,7 +1053,7 @@ if (__DEV__) { _substr3 = describeValueForErrorMessage(_value3); } - if (_name === expandedName) { + if (_name2 === expandedName) { start = str.length; length = _substr3.length; str += _substr3; @@ -2263,10 +2266,26 @@ if (__DEV__) { describeObjectForErrorMessage(parent, parentPropertyName) + "\nIf you need interactivity, consider converting part of this to a Client Component." ); + } else if ( + jsxChildrenParents.has(parent) || + (jsxPropsParents.has(parent) && parentPropertyName === "children") + ) { + var componentName = value.displayName || value.name || "Component"; + throw new Error( + "Functions are not valid as a child of Client Components. This may happen if " + + "you return " + + componentName + + " instead of <" + + componentName + + " /> from render. " + + "Or maybe you meant to call this function rather than return it." + + describeObjectForErrorMessage(parent, parentPropertyName) + ); } else { throw new Error( "Functions cannot be passed directly to Client Components " + - 'unless you explicitly expose it by marking it with "use server".' + + 'unless you explicitly expose it by marking it with "use server". ' + + "Or maybe you meant to call this function rather than return it." + describeObjectForErrorMessage(parent, parentPropertyName) ); } diff --git a/compiled/facebook-www/ReactFlightDOMServer-prod.modern.js b/compiled/facebook-www/ReactFlightDOMServer-prod.modern.js index 4d5095fdd2f64..9f2e816e86067 100644 --- a/compiled/facebook-www/ReactFlightDOMServer-prod.modern.js +++ b/compiled/facebook-www/ReactFlightDOMServer-prod.modern.js @@ -351,7 +351,11 @@ function describeValueForErrorMessage(value) { value = objectName(value); return "Object" === value ? "{...}" : value; case "function": - return value.$$typeof === CLIENT_REFERENCE_TAG ? "client" : "function"; + return value.$$typeof === CLIENT_REFERENCE_TAG + ? "client" + : (value = value.displayName || value.name) + ? "function " + value + : "function"; default: return String(value); } @@ -920,10 +924,10 @@ function renderModelDestructive( } if ("symbol" === typeof value) { task = request.writtenSymbols; - var existingId$8 = task.get(value); - if (void 0 !== existingId$8) return serializeByValueID(existingId$8); - existingId$8 = value.description; - if (Symbol.for(existingId$8) !== value) + var existingId$9 = task.get(value); + if (void 0 !== existingId$9) return serializeByValueID(existingId$9); + existingId$9 = value.description; + if (Symbol.for(existingId$9) !== value) throw Error( "Only global symbols received from Symbol.for(...) can be passed to Client Components. The symbol Symbol.for(" + (value.description + ") cannot be found among global symbols.") + @@ -931,7 +935,7 @@ function renderModelDestructive( ); request.pendingChunks++; parent = request.nextChunkId++; - parentPropertyName = stringify("$S" + existingId$8); + parentPropertyName = stringify("$S" + existingId$9); parentPropertyName = parent.toString(16) + ":" + parentPropertyName + "\n"; request.completedImportChunks.push(parentPropertyName); task.set(value, parent); diff --git a/compiled/facebook-www/ReactTestRenderer-dev.modern.js b/compiled/facebook-www/ReactTestRenderer-dev.modern.js index 4a132341ae787..a1608eee1a786 100644 --- a/compiled/facebook-www/ReactTestRenderer-dev.modern.js +++ b/compiled/facebook-www/ReactTestRenderer-dev.modern.js @@ -26067,7 +26067,7 @@ if (__DEV__) { return root; } - var ReactVersion = "18.3.0-www-modern-f239ff56"; + var ReactVersion = "18.3.0-www-modern-c4de807b"; // Might add PROFILE later.