Browse Source

Handle nested providers (#9)

Brent Vatne 4 years ago
parent
commit
ab69d5a626
1 changed files with 21 additions and 10 deletions
  1. 21
    10
      src/index.tsx

+ 21
- 10
src/index.tsx View File

1
 import * as React from 'react';
1
 import * as React from 'react';
2
-import { StyleSheet } from 'react-native';
2
+import { StyleSheet, View } from 'react-native';
3
 import { EdgeInsets, InsetChangedEvent } from './SafeArea.types';
3
 import { EdgeInsets, InsetChangedEvent } from './SafeArea.types';
4
 import NativeSafeAreaView from './NativeSafeAreaView';
4
 import NativeSafeAreaView from './NativeSafeAreaView';
5
 
5
 
10
 }
10
 }
11
 
11
 
12
 export function SafeAreaProvider({ children }: SafeAreaViewProps) {
12
 export function SafeAreaProvider({ children }: SafeAreaViewProps) {
13
+  let parentInsets = useParentSafeArea();
13
   const [insets, setInsets] = React.useState<EdgeInsets | null>(null);
14
   const [insets, setInsets] = React.useState<EdgeInsets | null>(null);
14
   const onInsetsChange = React.useCallback((event: InsetChangedEvent) => {
15
   const onInsetsChange = React.useCallback((event: InsetChangedEvent) => {
15
     setInsets(event.nativeEvent.insets);
16
     setInsets(event.nativeEvent.insets);
16
   }, []);
17
   }, []);
17
 
18
 
18
-  return (
19
-    <NativeSafeAreaView style={styles.fill} onInsetsChange={onInsetsChange}>
20
-      {insets !== null ? (
21
-        <SafeAreaContext.Provider value={insets}>
22
-          {children}
23
-        </SafeAreaContext.Provider>
24
-      ) : null}
25
-    </NativeSafeAreaView>
26
-  );
19
+  // If a provider is nested inside of another provider then we can just use
20
+  // the parent insets, without rendering another native safe area view
21
+  if (parentInsets) {
22
+    return <View style={styles.fill}>{children}</View>;
23
+  } else {
24
+    return (
25
+      <NativeSafeAreaView style={styles.fill} onInsetsChange={onInsetsChange}>
26
+        {insets !== null ? (
27
+          <SafeAreaContext.Provider value={insets}>
28
+            {children}
29
+          </SafeAreaContext.Provider>
30
+        ) : null}
31
+      </NativeSafeAreaView>
32
+    );
33
+  }
27
 }
34
 }
28
 
35
 
29
 const styles = StyleSheet.create({
36
 const styles = StyleSheet.create({
32
 
39
 
33
 export const SafeAreaConsumer = SafeAreaContext.Consumer;
40
 export const SafeAreaConsumer = SafeAreaContext.Consumer;
34
 
41
 
42
+function useParentSafeArea(): React.ContextType<typeof SafeAreaContext> {
43
+  return React.useContext(SafeAreaContext);
44
+}
45
+
35
 export function useSafeArea(): EdgeInsets {
46
 export function useSafeArea(): EdgeInsets {
36
   const safeArea = React.useContext(SafeAreaContext);
47
   const safeArea = React.useContext(SafeAreaContext);
37
   if (safeArea == null) {
48
   if (safeArea == null) {