From 9247407c70eff280768e605637be873052ac1b59 Mon Sep 17 00:00:00 2001
From: dan <dan.abramov@gmail.com>
Date: Sun, 10 Nov 2024 23:03:55 +0000
Subject: Don't render unnecessary <Portal> instances (#6217)

---
 .../src/BottomSheetNativeComponent.tsx             | 80 +++++++++++++---------
 1 file changed, 46 insertions(+), 34 deletions(-)

(limited to 'modules/bottom-sheet/src/BottomSheetNativeComponent.tsx')

diff --git a/modules/bottom-sheet/src/BottomSheetNativeComponent.tsx b/modules/bottom-sheet/src/BottomSheetNativeComponent.tsx
index fa2b163bf..acd46ce01 100644
--- a/modules/bottom-sheet/src/BottomSheetNativeComponent.tsx
+++ b/modules/bottom-sheet/src/BottomSheetNativeComponent.tsx
@@ -11,6 +11,7 @@ import {requireNativeModule, requireNativeViewManager} from 'expo-modules-core'
 
 import {BottomSheetState, BottomSheetViewProps} from './BottomSheet.types'
 import {BottomSheetPortalProvider} from './BottomSheetPortal'
+import {Context as PortalContext} from './BottomSheetPortal'
 
 const screenHeight = Dimensions.get('screen').height
 
@@ -34,6 +35,8 @@ export class BottomSheetNativeComponent extends React.Component<
 > {
   ref = React.createRef<any>()
 
+  static contextType = PortalContext
+
   constructor(props: BottomSheetViewProps) {
     super(props)
     this.state = {
@@ -67,6 +70,17 @@ export class BottomSheetNativeComponent extends React.Component<
   }
 
   render() {
+    const Portal = this.context as React.ContextType<typeof PortalContext>
+    if (!Portal) {
+      throw new Error(
+        'BottomSheet: You need to wrap your component tree with a <BottomSheetPortalProvider> to use the bottom sheet.',
+      )
+    }
+
+    if (!this.state.open) {
+      return null
+    }
+
     const {children, backgroundColor, ...rest} = this.props
     const cornerRadius = rest.cornerRadius ?? 0
 
@@ -83,43 +97,41 @@ export class BottomSheetNativeComponent extends React.Component<
       }
     }
 
-    if (!this.state.open) {
-      return null
-    }
-
     return (
-      <NativeView
-        {...rest}
-        onStateChange={this.onStateChange}
-        ref={this.ref}
-        style={{
-          position: 'absolute',
-          height: screenHeight,
-          width: '100%',
-        }}
-        containerBackgroundColor={backgroundColor}>
-        <View
-          style={[
-            {
-              flex: 1,
-              backgroundColor,
-            },
-            Platform.OS === 'android' && {
-              borderTopLeftRadius: cornerRadius,
-              borderTopRightRadius: cornerRadius,
-            },
-            extraStyles,
-          ]}>
+      <Portal>
+        <NativeView
+          {...rest}
+          onStateChange={this.onStateChange}
+          ref={this.ref}
+          style={{
+            position: 'absolute',
+            height: screenHeight,
+            width: '100%',
+          }}
+          containerBackgroundColor={backgroundColor}>
           <View
-            onLayout={e => {
-              const {height} = e.nativeEvent.layout
-              this.setState({viewHeight: height})
-              this.updateLayout()
-            }}>
-            <BottomSheetPortalProvider>{children}</BottomSheetPortalProvider>
+            style={[
+              {
+                flex: 1,
+                backgroundColor,
+              },
+              Platform.OS === 'android' && {
+                borderTopLeftRadius: cornerRadius,
+                borderTopRightRadius: cornerRadius,
+              },
+              extraStyles,
+            ]}>
+            <View
+              onLayout={e => {
+                const {height} = e.nativeEvent.layout
+                this.setState({viewHeight: height})
+                this.updateLayout()
+              }}>
+              <BottomSheetPortalProvider>{children}</BottomSheetPortalProvider>
+            </View>
           </View>
-        </View>
-      </NativeView>
+        </NativeView>
+      </Portal>
     )
   }
 }
-- 
cgit 1.4.1

