diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js index c7506a13e5941..0afc8ef4834d6 100644 --- a/packages/react-client/src/ReactFlightClient.js +++ b/packages/react-client/src/ReactFlightClient.js @@ -524,16 +524,24 @@ function moveDebugInfoFromChunkToInnerValue( debugInfo, ); } else { - Object.defineProperty((resolvedValue: any), '_debugInfo', { - configurable: false, - enumerable: false, - writable: true, - value: debugInfo, - }); + setDebugInfo(resolvedValue, debugInfo); } } } +function setDebugInfo(value: any, debugInfo: Array) { + // Only set if property is writable. If the value is a JSX element, it will be frozen. + const descriptor = Object.getOwnPropertyDescriptor(value, '_debugInfo'); + if (!descriptor || descriptor.writable) { + Object.defineProperty(value, '_debugInfo', { + configurable: false, + enumerable: false, + writable: true, + value: debugInfo, + }); + } +} + function wakeChunk( listeners: Array mixed)>, value: T, @@ -1219,12 +1227,7 @@ function initializeElement( // $FlowFixMe[method-unbinding] element._debugInfo.unshift.apply(element._debugInfo, debugInfo); } else { - Object.defineProperty(element, '_debugInfo', { - configurable: false, - enumerable: false, - writable: true, - value: debugInfo, - }); + setDebugInfo(element, debugInfo); } } } @@ -2797,12 +2800,7 @@ function addAsyncInfo(chunk: SomeChunk, asyncInfo: ReactAsyncInfo): void { // $FlowFixMe[method-unbinding] value._debugInfo.push(asyncInfo); } else { - Object.defineProperty((value: any), '_debugInfo', { - configurable: false, - enumerable: false, - writable: true, - value: [asyncInfo], - }); + setDebugInfo(value, [asyncInfo]); } } else { // $FlowFixMe[method-unbinding] diff --git a/packages/react-client/src/__tests__/ReactFlight-test.js b/packages/react-client/src/__tests__/ReactFlight-test.js index b0f539bf2572c..8a9a1d093b75f 100644 --- a/packages/react-client/src/__tests__/ReactFlight-test.js +++ b/packages/react-client/src/__tests__/ReactFlight-test.js @@ -3884,4 +3884,24 @@ describe('ReactFlight', () => { , ); }); + + it('does not crash when exporting a JSX element as a client reference', async () => { + const ClientReference = clientReference(React.createElement('div')); + + function App() { + return ClientReference; + } + + const transport = ReactNoopFlightServer.render({ + root: ReactServer.createElement(App), + }); + + await act(async () => { + const {root} = await ReactNoopFlightClient.read(transport); + ReactNoop.render(root); + if (__DEV__) { + expect(getDebugInfo(root)).toBeNull(); + } + }); + }); });