[Flight] Handle bound arguments for loaded server references (#31302)
Follow up to #31300. I forgot to pass the bound arguments to the loaded function.
Sebastian Markbåge committed
Oct 20, 2024 at 02:12 UTC
251b666dedde430b7767e1745e71155db8ec585d
2 files changed
+20
-7
packages/react-client/src/ReactFlightClient.js
+12
-3
@@ -1073,10 +1073,11 @@ function loadServerReference<A: Iterable<any>, T>(
1073
metaData.id,
1074
);
1075
1076
- const promise = preloadModule(serverReference);
1077
- if (!promise) {
1076
+ let promise = preloadModule(serverReference);
1077
+ if (!promise && !metaData.bound) {
1078
return (requireModule(serverReference): any);
1079
}
1080
+ promise = Promise.all([promise, metaData.bound]);
1081
1082
let handler: InitializationHandler;
1083
if (initializingHandler) {
@@ -1093,7 +1094,15 @@ function loadServerReference<A: Iterable<any>, T>(
1094
}
1095
1096
function fulfill(): void {
1096
- const resolvedValue = (requireModule(serverReference): any);
1097
+ let resolvedValue = (requireModule(serverReference): any);
1098
+
1099
+ if (metaData.bound) {
1100
+ // This promise is coming from us and should have initilialized by now.
1101
+ const boundArgs: Array<any> = (metaData.bound: any).value.slice(0);
1102
+ boundArgs.unshift(null); // this
1103
+ resolvedValue = resolvedValue.bind.apply(resolvedValue, boundArgs);
1104
+ }
1105
+
1106
parentObject[key] = resolvedValue;
1107
1108
// If this is the root object for a model reference, where `handler.value`
packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js
+8
-4
@@ -215,8 +215,8 @@ describe('ReactFlightDOMEdge', () => {
215
});
216
217
it('should be able to load a server reference on a consuming server if a mapping exists', async () => {
218
- function greet() {
219
- return 'hi';
218
+ function greet(name) {
219
+ return 'hi, ' + name;
220
}
221
const ServerModule = serverExports({
222
greet,
@@ -226,6 +226,7 @@ describe('ReactFlightDOMEdge', () => {
226
ReactServerDOMServer.renderToReadableStream(
227
{
228
method: ServerModule.greet,
229
+ boundMethod: ServerModule.greet.bind(null, 'there'),
230
},
231
webpackMap,
232
),
@@ -241,14 +242,15 @@ describe('ReactFlightDOMEdge', () => {
242
const result = await response;
243
244
expect(result.method).toBe(greet);
245
+ expect(result.boundMethod()).toBe('hi, there');
246
});
247
248
it('should be able to load a server reference on a consuming server if a mapping exists (async)', async () => {
249
let resolve;
250
const chunkPromise = new Promise(r => (resolve = r));
251
250
- function greet() {
251
- return 'hi';
252
+ function greet(name) {
253
+ return 'hi, ' + name;
254
}
255
const ServerModule = serverExports(
256
{
@@ -261,6 +263,7 @@ describe('ReactFlightDOMEdge', () => {
263
ReactServerDOMServer.renderToReadableStream(
264
{
265
method: ServerModule.greet,
266
+ boundMethod: ServerModule.greet.bind(null, 'there'),
267
},
268
webpackMap,
269
),
@@ -278,6 +281,7 @@ describe('ReactFlightDOMEdge', () => {
281
const result = await response;
282
283
expect(result.method).toBe(greet);
284
+ expect(result.boundMethod()).toBe('hi, there');
285
});
286
287
it('should encode long string in a compact format', async () => {