From e2ac6473765f808fbc064efd0359bbfa65d21d77 Mon Sep 17 00:00:00 2001 From: Luna Ruan Date: Tue, 15 Dec 2020 15:33:54 -0800 Subject: [PATCH] clone json obj in relay flight client host config parser (#20465) When `parseModel` suspends because of missing dependencies, it will exit and retry to parse later. However, in the relay implementation, the model is an object that we modify in place when we parse it, so when we we retry, part of the model might be parsed already into React elements, which will error because the parsing code expect a Flight model. This diff clones instead of mutating the original model, which fixes this error. --- .../src/ReactFlightDOMRelayClientHostConfig.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/react-server-dom-relay/src/ReactFlightDOMRelayClientHostConfig.js b/packages/react-server-dom-relay/src/ReactFlightDOMRelayClientHostConfig.js index f816443781700..09dd7df1d5533 100644 --- a/packages/react-server-dom-relay/src/ReactFlightDOMRelayClientHostConfig.js +++ b/packages/react-server-dom-relay/src/ReactFlightDOMRelayClientHostConfig.js @@ -36,18 +36,25 @@ function parseModelRecursively(response: Response, parentObj, value) { } if (typeof value === 'object' && value !== null) { if (Array.isArray(value)) { + const parsedValue = []; for (let i = 0; i < value.length; i++) { - (value: any)[i] = parseModelRecursively(response, value, value[i]); + (parsedValue: any)[i] = parseModelRecursively( + response, + value, + value[i], + ); } - return parseModelTuple(response, value); + return parseModelTuple(response, parsedValue); } else { + const parsedValue = {}; for (const innerKey in value) { - (value: any)[innerKey] = parseModelRecursively( + (parsedValue: any)[innerKey] = parseModelRecursively( response, value, value[innerKey], ); } + return parsedValue; } } return value;