Skip to content

Commit

Permalink
[Flight] Support FormData from Server to Client (#28754)
Browse files Browse the repository at this point in the history
We currently support FormData for Replies mainly for Form Actions. This
supports it in the other direction too which lets you return it from an
action as the response. Mainly for parity.

We don't really recommend that you just pass the original form data back
because the action is supposed to be able to clear fields and such but
you could potentially at least use this as the format and could clear
some fields.

We could potentially optimize this with a temporary reference if the
same object was passed to a reply in case you use it as a round trip to
avoid serializing it back again. That way the action has the ability to
override it to clear fields but if it doesn't you get back the same as
you sent.

#28755 adds support for Blobs when the `enableBinaryFlight` is enabled
which allows them to be used inside FormData too.

DiffTrain build for [2acfb7b](2acfb7b)
  • Loading branch information
sebmarkbage committed Apr 5, 2024
1 parent 2cfe8d3 commit c093e5b
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 3 deletions.
2 changes: 1 addition & 1 deletion compiled/facebook-www/REVISION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
d1547defe34cee6326a61059148afc83228d8ecf
2acfb7b60922bdc8376dd144ca7bc532df78254b
19 changes: 17 additions & 2 deletions compiled/facebook-www/ReactFlightDOMClient-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,21 @@ if (__DEV__) {
return undefined;
}

case "K": {
// FormData
var _id7 = parseInt(value.slice(2), 16);

var _data3 = getOutlinedModel(response, _id7);

var formData = new FormData();

for (var i = 0; i < _data3.length; i++) {
formData.append(_data3[i][0], _data3[i][1]);
}

return formData;
}

case "I": {
// $Infinity
return Infinity;
Expand Down Expand Up @@ -891,9 +906,9 @@ if (__DEV__) {

default: {
// We assume that anything else is a reference ID.
var _id7 = parseInt(value.slice(1), 16);
var _id8 = parseInt(value.slice(1), 16);

var _chunk2 = getChunk(response, _id7);
var _chunk2 = getChunk(response, _id8);

switch (_chunk2.status) {
case RESOLVED_MODEL:
Expand Down
7 changes: 7 additions & 0 deletions compiled/facebook-www/ReactFlightDOMClient-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,13 @@ function parseModelString(response, parentObject, key, value) {
);
case "B":
return;
case "K":
parentObject = parseInt(value.slice(2), 16);
response = getOutlinedModel(response, parentObject);
parentObject = new FormData();
for (key = 0; key < response.length; key++)
parentObject.append(response[key][0], response[key][1]);
return parentObject;
case "I":
return Infinity;
case "-":
Expand Down
14 changes: 14 additions & 0 deletions compiled/facebook-www/ReactFlightDOMServer-dev.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -2032,6 +2032,12 @@ if (__DEV__) {
return "$Q" + id.toString(16);
}

function serializeFormData(request, formData) {
var entries = Array.from(formData.entries());
var id = outlineModel(request, entries);
return "$K" + id.toString(16);
}

function serializeSet(request, set) {
var entries = Array.from(set);

Expand Down Expand Up @@ -2338,6 +2344,10 @@ if (__DEV__) {

if (value instanceof Set) {
return serializeSet(request, value);
} // TODO: FormData is not available in old Node. Remove the typeof later.

if (typeof FormData === "function" && value instanceof FormData) {
return serializeFormData(request, value);
}

var iteratorFn = getIteratorFn(value);
Expand Down Expand Up @@ -2730,6 +2740,10 @@ if (__DEV__) {

if (value instanceof Set) {
return serializeSet(request, value);
} // TODO: FormData is not available in old Node. Remove the typeof later.

if (typeof FormData === "function" && value instanceof FormData) {
return serializeFormData(request, value);
}

var iteratorFn = getIteratorFn(value);
Expand Down
5 changes: 5 additions & 0 deletions compiled/facebook-www/ReactFlightDOMServer-prod.modern.js
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,11 @@ function renderModelDestructive(
parentPropertyName.set(parent, -1));
return "$W" + outlineModel(request, value).toString(16);
}
if ("function" === typeof FormData && value instanceof FormData)
return (
(value = Array.from(value.entries())),
"$K" + outlineModel(request, value).toString(16)
);
null === value || "object" !== typeof value
? (parent = null)
: ((parent =
Expand Down

0 comments on commit c093e5b

Please sign in to comment.