@@ -5,14 +5,15 @@ import BottomTabsScreenNativeComponent, {
5
5
type NativeProps ,
6
6
} from '../fabric/BottomTabsScreenNativeComponent' ;
7
7
import {
8
- ColorValue ,
9
- NativeSyntheticEvent ,
8
+ type ColorValue ,
9
+ type NativeSyntheticEvent ,
10
10
StyleSheet ,
11
- ViewProps ,
11
+ type ViewProps ,
12
12
findNodeHandle ,
13
13
} from 'react-native' ;
14
14
import { Freeze } from 'react-freeze' ;
15
15
import { freezeEnabled } from '../core' ;
16
+ import { featureFlags } from '../flags' ;
16
17
17
18
export type EmptyObject = Record < string , never > ;
18
19
export type BottomTabsScreenEventHandler < T > = (
@@ -24,6 +25,8 @@ export interface BottomTabsScreenProps {
24
25
placeholder ?: React . ReactNode | undefined ;
25
26
26
27
// Control
28
+
29
+ // Works only in 'controlled' mode. Otherwise this prop indicates only initally selected tab.
27
30
isFocused ?: boolean ;
28
31
tabKey : string ;
29
32
@@ -41,21 +44,6 @@ export interface BottomTabsScreenProps {
41
44
}
42
45
43
46
function BottomTabsScreen ( props : BottomTabsScreenProps ) {
44
- const [ nativeViewHasDisappeared , setNativeViewHasDisappeared ] =
45
- React . useState ( true ) ;
46
-
47
- const {
48
- onWillAppear,
49
- onDidAppear,
50
- onWillDisappear,
51
- onDidDisappear,
52
- isFocused = false ,
53
- ...propsWoEventHandlers
54
- } = props ;
55
-
56
- const shouldFreeze =
57
- freezeEnabled ( ) && ! isFocused && nativeViewHasDisappeared ;
58
-
59
47
const componentNodeRef = React . useRef < React . Component < NativeProps > > ( null ) ;
60
48
const componentNodeHandle = React . useRef < number > ( - 1 ) ;
61
49
@@ -68,12 +56,37 @@ function BottomTabsScreen(props: BottomTabsScreenProps) {
68
56
}
69
57
} , [ ] ) ;
70
58
59
+ const [ nativeViewIsVisible , setNativeViewIsVisible ] = React . useState ( false ) ;
60
+
61
+ const {
62
+ onWillAppear,
63
+ onDidAppear,
64
+ onWillDisappear,
65
+ onDidDisappear,
66
+ isFocused = false ,
67
+ ...propsWoEventHandlers
68
+ } = props ;
69
+
70
+ let shouldFreeze = freezeEnabled ( ) ;
71
+
72
+ if ( featureFlags . experiment . controlledBottomTabs ) {
73
+ // If the tabs are JS controlled, we want to freeze only when given view is not focused && it is not currently visible
74
+ shouldFreeze = shouldFreeze && ! nativeViewIsVisible && ! isFocused ;
75
+ console . info (
76
+ `TabsScreen [${ componentNodeHandle . current ?? - 1 } ] render; tabKey: ${
77
+ propsWoEventHandlers . tabKey
78
+ } UPDATE DUE TO CONTROLLED TABS TO shouldFreeze: ${ shouldFreeze } `,
79
+ ) ;
80
+ } else {
81
+ shouldFreeze = shouldFreeze && ! nativeViewIsVisible ;
82
+ }
83
+
71
84
const onWillAppearCallback = React . useCallback (
72
85
( event : NativeSyntheticEvent < EmptyObject > ) => {
73
86
console . log (
74
87
`TabsScreen [${ componentNodeHandle . current } ] onWillAppear received` ,
75
88
) ;
76
- setNativeViewHasDisappeared ( false ) ;
89
+ setNativeViewIsVisible ( true ) ;
77
90
onWillAppear ?.( event ) ;
78
91
} ,
79
92
[ onWillAppear ] ,
@@ -104,16 +117,16 @@ function BottomTabsScreen(props: BottomTabsScreenProps) {
104
117
console . log (
105
118
`TabsScreen [${ componentNodeHandle . current } ] onDidDisappear received` ,
106
119
) ;
107
- setNativeViewHasDisappeared ( true ) ;
120
+ setNativeViewIsVisible ( false ) ;
108
121
onDidDisappear ?.( event ) ;
109
122
} ,
110
123
[ onDidDisappear ] ,
111
124
) ;
112
125
113
126
console . info (
114
- `TabsScreen [${
115
- componentNodeHandle . current ?? - 1
116
- } ] render; shouldFreeze: ${ shouldFreeze } , isFocused: ${ isFocused } nativeViewHasDisappeared : ${ nativeViewHasDisappeared } `,
127
+ `TabsScreen [${ componentNodeHandle . current ?? - 1 } ] render; tabKey: ${
128
+ propsWoEventHandlers . tabKey
129
+ } shouldFreeze: ${ shouldFreeze } , isFocused: ${ isFocused } nativeViewIsVisible : ${ nativeViewIsVisible } `,
117
130
) ;
118
131
119
132
return (
0 commit comments