From 2d9d96bce9d161199be0f35438413d19de1dc522 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Thu, 9 Mar 2023 21:25:41 +0000 Subject: [PATCH] [Flight] Add support for returning `undefined` from render (#26349) ## Summary Adds support for returning `undefined` from Server Components. Also fixes a bug where rendering an empty fragment would throw the same error as returning undefined. ## How did you test this change? - [x] test failed with same error message I got when returning undefined from Server Components in a Next.js app - [x] test passes after adding encoding for `undefined` DiffTrain build for [d1ad984db1591b131d16739a24dee4ba44886a09](https://github.com/facebook/react/commit/d1ad984db1591b131d16739a24dee4ba44886a09) --- compiled/facebook-www/REVISION | 2 +- .../ReactFlightDOMRelayClient-dev.classic.js | 6 ++++++ .../ReactFlightDOMRelayClient-dev.modern.js | 6 ++++++ .../ReactFlightDOMRelayClient-prod.classic.js | 2 ++ .../ReactFlightDOMRelayClient-prod.modern.js | 2 ++ .../ReactFlightDOMRelayServer-dev.classic.js | 14 +++++++++----- .../ReactFlightDOMRelayServer-dev.modern.js | 14 +++++++++----- .../ReactFlightDOMRelayServer-prod.classic.js | 8 ++------ .../ReactFlightDOMRelayServer-prod.modern.js | 8 ++------ 9 files changed, 39 insertions(+), 23 deletions(-) diff --git a/compiled/facebook-www/REVISION b/compiled/facebook-www/REVISION index 2887e9ebbc911..63a9297f7518b 100644 --- a/compiled/facebook-www/REVISION +++ b/compiled/facebook-www/REVISION @@ -1 +1 @@ -3706edb81c84ea01e68bfb477537ba9908e1bd70 +d1ad984db1591b131d16739a24dee4ba44886a09 diff --git a/compiled/facebook-www/ReactFlightDOMRelayClient-dev.classic.js b/compiled/facebook-www/ReactFlightDOMRelayClient-dev.classic.js index 1d4b8e7cb5655..667548e29eb33 100644 --- a/compiled/facebook-www/ReactFlightDOMRelayClient-dev.classic.js +++ b/compiled/facebook-www/ReactFlightDOMRelayClient-dev.classic.js @@ -555,6 +555,12 @@ function parseModelString(response, parentObject, key, value) { } } + case "u": { + // matches "$undefined" + // Special encoding for `undefined` which can't be serialized as JSON otherwise. + return undefined; + } + default: { // We assume that anything else is a reference ID. var _id3 = parseInt(value.substring(1), 16); diff --git a/compiled/facebook-www/ReactFlightDOMRelayClient-dev.modern.js b/compiled/facebook-www/ReactFlightDOMRelayClient-dev.modern.js index 1d4b8e7cb5655..667548e29eb33 100644 --- a/compiled/facebook-www/ReactFlightDOMRelayClient-dev.modern.js +++ b/compiled/facebook-www/ReactFlightDOMRelayClient-dev.modern.js @@ -555,6 +555,12 @@ function parseModelString(response, parentObject, key, value) { } } + case "u": { + // matches "$undefined" + // Special encoding for `undefined` which can't be serialized as JSON otherwise. + return undefined; + } + default: { // We assume that anything else is a reference ID. var _id3 = parseInt(value.substring(1), 16); diff --git a/compiled/facebook-www/ReactFlightDOMRelayClient-prod.classic.js b/compiled/facebook-www/ReactFlightDOMRelayClient-prod.classic.js index a6ca82504fcc9..14c6413cc6e92 100644 --- a/compiled/facebook-www/ReactFlightDOMRelayClient-prod.classic.js +++ b/compiled/facebook-www/ReactFlightDOMRelayClient-prod.classic.js @@ -282,6 +282,8 @@ function parseModelString(response, parentObject, key, value) { default: throw parentObject.reason; } + case "u": + return; default: value = parseInt(value.substring(1), 16); response = getChunk(response, value); diff --git a/compiled/facebook-www/ReactFlightDOMRelayClient-prod.modern.js b/compiled/facebook-www/ReactFlightDOMRelayClient-prod.modern.js index a6ca82504fcc9..14c6413cc6e92 100644 --- a/compiled/facebook-www/ReactFlightDOMRelayClient-prod.modern.js +++ b/compiled/facebook-www/ReactFlightDOMRelayClient-prod.modern.js @@ -282,6 +282,8 @@ function parseModelString(response, parentObject, key, value) { default: throw parentObject.reason; } + case "u": + return; default: value = parseInt(value.substring(1), 16); response = getChunk(response, value); diff --git a/compiled/facebook-www/ReactFlightDOMRelayServer-dev.classic.js b/compiled/facebook-www/ReactFlightDOMRelayServer-dev.classic.js index e39bdb4971572..4968367502b83 100644 --- a/compiled/facebook-www/ReactFlightDOMRelayServer-dev.classic.js +++ b/compiled/facebook-www/ReactFlightDOMRelayServer-dev.classic.js @@ -1637,6 +1637,10 @@ function serializeProviderReference(name) { return "$P" + name; } +function serializeUndefined() { + return "$undefined"; +} + function serializeClientReference(request, parent, key, clientReference) { var clientReferenceKey = getClientReferenceKey(clientReference); var writtenClientReferences = request.writtenClientReferences; @@ -2235,14 +2239,14 @@ function resolveModelToJSON(request, parent, key, value) { return escapeStringValue(value); } - if ( - typeof value === "boolean" || - typeof value === "number" || - typeof value === "undefined" - ) { + if (typeof value === "boolean" || typeof value === "number") { return value; } + if (typeof value === "undefined") { + return serializeUndefined(); + } + if (typeof value === "function") { if (isClientReference(value)) { return serializeClientReference(request, parent, key, value); diff --git a/compiled/facebook-www/ReactFlightDOMRelayServer-dev.modern.js b/compiled/facebook-www/ReactFlightDOMRelayServer-dev.modern.js index 49525810e81cf..dce7a5bfbb6a6 100644 --- a/compiled/facebook-www/ReactFlightDOMRelayServer-dev.modern.js +++ b/compiled/facebook-www/ReactFlightDOMRelayServer-dev.modern.js @@ -1637,6 +1637,10 @@ function serializeProviderReference(name) { return "$P" + name; } +function serializeUndefined() { + return "$undefined"; +} + function serializeClientReference(request, parent, key, clientReference) { var clientReferenceKey = getClientReferenceKey(clientReference); var writtenClientReferences = request.writtenClientReferences; @@ -2235,14 +2239,14 @@ function resolveModelToJSON(request, parent, key, value) { return escapeStringValue(value); } - if ( - typeof value === "boolean" || - typeof value === "number" || - typeof value === "undefined" - ) { + if (typeof value === "boolean" || typeof value === "number") { return value; } + if (typeof value === "undefined") { + return serializeUndefined(); + } + if (typeof value === "function") { if (isClientReference(value)) { return serializeClientReference(request, parent, key, value); diff --git a/compiled/facebook-www/ReactFlightDOMRelayServer-prod.classic.js b/compiled/facebook-www/ReactFlightDOMRelayServer-prod.classic.js index 9821730241ea5..149f03935b975 100644 --- a/compiled/facebook-www/ReactFlightDOMRelayServer-prod.classic.js +++ b/compiled/facebook-www/ReactFlightDOMRelayServer-prod.classic.js @@ -937,12 +937,8 @@ function resolveModelToJSON(request, parent, key, value) { } if ("string" === typeof value) return (request = "$" === value[0] ? "$" + value : value), request; - if ( - "boolean" === typeof value || - "number" === typeof value || - "undefined" === typeof value - ) - return value; + if ("boolean" === typeof value || "number" === typeof value) return value; + if ("undefined" === typeof value) return "$undefined"; if ("function" === typeof value) { if (value instanceof JSResourceReferenceImpl) return serializeClientReference(request, parent, key, value); diff --git a/compiled/facebook-www/ReactFlightDOMRelayServer-prod.modern.js b/compiled/facebook-www/ReactFlightDOMRelayServer-prod.modern.js index 9821730241ea5..149f03935b975 100644 --- a/compiled/facebook-www/ReactFlightDOMRelayServer-prod.modern.js +++ b/compiled/facebook-www/ReactFlightDOMRelayServer-prod.modern.js @@ -937,12 +937,8 @@ function resolveModelToJSON(request, parent, key, value) { } if ("string" === typeof value) return (request = "$" === value[0] ? "$" + value : value), request; - if ( - "boolean" === typeof value || - "number" === typeof value || - "undefined" === typeof value - ) - return value; + if ("boolean" === typeof value || "number" === typeof value) return value; + if ("undefined" === typeof value) return "$undefined"; if ("function" === typeof value) { if (value instanceof JSResourceReferenceImpl) return serializeClientReference(request, parent, key, value);