From dee1467a3ec2e9bcd8b5c956749789b994d4fbb3 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Wed, 29 Nov 2023 11:55:07 -0800 Subject: [PATCH] [fix] 'render' export uses ReactDOM.createRoot AppRegistry.runApplication uses `ReactDOM.createRoot` by default, but the `render` export uses the legacy `ReactDOM.render`. This patch makes those 2 APIs consistent. It also makes some adjustments to the `createSheet` internals to more reliably implement and test style sheet replication within ShadowRoot's and iframes. Fix #2612 --- .../pages/app-registry/index.js | 160 ++++++++++++++---- .../__snapshots__/index-test.js.snap | 101 +++++++++++ .../AppRegistry/__tests__/index-test.js | 63 ++++--- .../exports/AppRegistry/renderApplication.js | 3 +- .../exports/StyleSheet/__tests__/dom-test.js | 22 +-- .../StyleSheet/dom/createCSSStyleSheet.js | 11 +- .../src/exports/StyleSheet/dom/index.js | 26 ++- .../src/exports/render/index.js | 32 ++-- 8 files changed, 308 insertions(+), 110 deletions(-) create mode 100644 packages/react-native-web/src/exports/AppRegistry/__tests__/__snapshots__/index-test.js.snap diff --git a/packages/react-native-web-examples/pages/app-registry/index.js b/packages/react-native-web-examples/pages/app-registry/index.js index 53d8f55743..168ea5efe9 100644 --- a/packages/react-native-web-examples/pages/app-registry/index.js +++ b/packages/react-native-web-examples/pages/app-registry/index.js @@ -1,51 +1,137 @@ -import React from 'react'; -import { AppRegistry, Text, StyleSheet } from 'react-native'; +import React, { useRef, useEffect, useState } from 'react'; +import { Pressable, Text, StyleSheet, View, render } from 'react-native'; import Example from '../../shared/example'; +function IframeWrapper({ children }) { + const iframeHost = useRef(); + const reactRoot = useRef(); + + useEffect(() => { + if (iframeHost.current) { + if (!reactRoot.current) { + const iframeElement = iframeHost.current; + const iframeAppContainer = document.createElement('div'); + iframeElement.contentWindow.document.body.appendChild( + iframeAppContainer + ); + reactRoot.current = render(children, iframeAppContainer); + } + reactRoot.current.render(children); + } + }); + + return