Skip to content

Commit 8f2f516

Browse files
committed
Add support for undefined in Replies to match client
1 parent ef8bdbe commit 8f2f516

File tree

3 files changed

+75
-5
lines changed

3 files changed

+75
-5
lines changed

packages/react-client/src/ReactFlightReplyClient.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export type ReactServerValue =
4646
| number
4747
| symbol
4848
| null
49+
| void
4950
| Iterable<ReactServerValue>
5051
| Array<ReactServerValue>
5152
| ReactServerObject
@@ -69,6 +70,10 @@ function serializeSymbolReference(name: string): string {
6970
return '$S' + name;
7071
}
7172

73+
function serializeUndefined(): string {
74+
return '$undefined';
75+
}
76+
7277
function escapeStringValue(value: string): string {
7378
if (value[0] === '$') {
7479
// We need to escape $ prefixed strings since we use those to encode
@@ -208,14 +213,14 @@ export function processReply(
208213
return escapeStringValue(value);
209214
}
210215

211-
if (
212-
typeof value === 'boolean' ||
213-
typeof value === 'number' ||
214-
typeof value === 'undefined'
215-
) {
216+
if (typeof value === 'boolean' || typeof value === 'number') {
216217
return value;
217218
}
218219

220+
if (typeof value === 'undefined') {
221+
return serializeUndefined();
222+
}
223+
219224
if (typeof value === 'function') {
220225
const metaData = knownServerReferences.get(value);
221226
if (metaData !== undefined) {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @emails react-core
8+
*/
9+
10+
'use strict';
11+
12+
// Polyfills for test environment
13+
global.ReadableStream =
14+
require('web-streams-polyfill/ponyfill/es6').ReadableStream;
15+
global.TextEncoder = require('util').TextEncoder;
16+
global.TextDecoder = require('util').TextDecoder;
17+
18+
// let serverExports;
19+
let webpackServerMap;
20+
let act;
21+
let ReactServerDOMServer;
22+
let ReactServerDOMClient;
23+
24+
describe('ReactFlightDOMReply', () => {
25+
beforeEach(() => {
26+
jest.resetModules();
27+
act = require('internal-test-utils').act;
28+
const WebpackMock = require('./utils/WebpackMock');
29+
// serverExports = WebpackMock.serverExports;
30+
webpackServerMap = WebpackMock.webpackServerMap;
31+
ReactServerDOMServer = require('react-server-dom-webpack/server.browser');
32+
ReactServerDOMClient = require('react-server-dom-webpack/client');
33+
});
34+
35+
it('can pass undefined as a reply', async () => {
36+
const body = await ReactServerDOMClient.encodeReply(undefined);
37+
const missing = await ReactServerDOMServer.decodeReply(
38+
body,
39+
webpackServerMap,
40+
);
41+
expect(missing).toBe(undefined);
42+
43+
const body2 = await ReactServerDOMClient.encodeReply({
44+
array: [undefined, null, undefined],
45+
prop: undefined,
46+
});
47+
const object = await ReactServerDOMServer.decodeReply(
48+
body2,
49+
webpackServerMap,
50+
);
51+
expect(object.array.length).toBe(3);
52+
expect(object.array[0]).toBe(undefined);
53+
expect(object.array[1]).toBe(null);
54+
expect(object.array[3]).toBe(undefined);
55+
expect(object.prop).toBe(undefined);
56+
// These should really be true but our deserialization doesn't currently deal with it.
57+
expect('3' in object.array).toBe(false);
58+
expect('prop' in object).toBe(false);
59+
});
60+
});

packages/react-server/src/ReactFlightReplyServer.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,11 @@ function parseModelString(
397397
key,
398398
);
399399
}
400+
case 'u': {
401+
// matches "$undefined"
402+
// Special encoding for `undefined` which can't be serialized as JSON otherwise.
403+
return undefined;
404+
}
400405
default: {
401406
// We assume that anything else is a reference ID.
402407
const id = parseInt(value.substring(1), 16);

0 commit comments

Comments
 (0)