Skip to content

Commit 01007d1

Browse files
authored
Use react-freeze to optimize TabController pages (#1639)
* Use react-freeze to optimize TabController pages * Improve TabPage freeze logic * Commet some code * Fix logic for handling focused pages in TabController * fix check in TabPage logic
1 parent e8c5e20 commit 01007d1

File tree

4 files changed

+36
-8
lines changed

4 files changed

+36
-8
lines changed

demo/src/screens/componentScreens/TabControllerScreen/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class TabControllerScreen extends Component<{}, State> {
119119
}
120120

121121
renderTabPages() {
122-
const {asCarousel} = this.state;
122+
const {asCarousel, fewItems} = this.state;
123123
const Container = asCarousel ? TabController.PageCarousel : View;
124124
const containerProps = asCarousel ? {} : {flex: true};
125125
return (
@@ -134,7 +134,7 @@ class TabControllerScreen extends Component<{}, State> {
134134
<Tab3/>
135135
</TabController.TabPage>
136136

137-
{_.map(_.takeRight(TABS, TABS.length - 3), (title, index) => {
137+
{!fewItems && _.map(_.takeRight(TABS, TABS.length - 3), (title, index) => {
138138
return (
139139
<TabController.TabPage key={title} index={index + 3}>
140140
<View padding-s5>

demo/src/screens/componentScreens/TabControllerScreen/tab3.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {Card, Avatar, View, Text} from 'react-native-ui-lib';
55

66
class Tab2 extends Component {
77
state = {
8+
counter: 0,
89
loading: true
910
};
1011

@@ -13,7 +14,17 @@ class Tab2 extends Component {
1314
this.setState({loading: false});
1415
}, 1200);
1516

16-
// this.slow();
17+
/* Uncomment to test TabPage freeze functionality when the page lose focus */
18+
// setInterval(() => {
19+
// this.setState({counter: this.state.counter + 1});
20+
// }, 1000);
21+
}
22+
23+
componentDidUpdate() {
24+
/* Uncomment to test TabPage freeze functionality when the page lose focus */
25+
// if (this.state.counter % 3 === 0) {
26+
// console.warn('freeze counter', this.state.counter);
27+
// }
1728
}
1829

1930
slow(iterations = 10) {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"memoize-one": "^5.0.5",
5353
"moment": "^2.24.0",
5454
"prop-types": "^15.5.10",
55+
"react-freeze": "^1.0.0",
5556
"react-native-color": "0.0.10",
5657
"react-native-redash": "^12.0.3",
5758
"react-native-text-size": "4.0.0-rc.1",

src/components/tabController/TabPage.tsx

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, {PropsWithChildren, useCallback, useContext, useState, useMemo} from 'react';
22
import {StyleSheet} from 'react-native';
33
import Reanimated, {useAnimatedStyle, useAnimatedReaction, runOnJS} from 'react-native-reanimated';
4+
import {Freeze} from 'react-freeze';
45
import TabBarContext from './TabBarContext';
56

67
export interface TabControllerPageProps {
@@ -37,8 +38,9 @@ export default function TabPage({
3738
renderLoading,
3839
...props
3940
}: PropsWithChildren<TabControllerPageProps>) {
40-
const {currentPage, targetPage, asCarousel, containerWidth} = useContext(TabBarContext);
41+
const {currentPage, asCarousel, containerWidth} = useContext(TabBarContext);
4142
const [shouldLoad, setLoaded] = useState(!lazy);
43+
const [focused, setFocused] = useState(false);
4244

4345
const lazyLoad = useCallback(() => {
4446
if (lazy && !shouldLoad) {
@@ -47,13 +49,26 @@ export default function TabPage({
4749
}, [lazy, shouldLoad]);
4850

4951
useAnimatedReaction(() => {
50-
return targetPage.value === index;
52+
return currentPage.value;
5153
},
52-
isActive => {
54+
(currentPage, previousPage) => {
55+
const isActive = currentPage === index;
56+
const wasActive = previousPage === index;
57+
const nearActive = asCarousel && (currentPage - 1 === index || currentPage + 1 === index);
58+
const wasNearActive =
59+
asCarousel && previousPage !== null && (previousPage - 1 === index || previousPage + 1 === index);
60+
5361
if (isActive) {
5462
runOnJS(lazyLoad)();
5563
}
56-
});
64+
65+
if (isActive || nearActive) {
66+
runOnJS(setFocused)(true);
67+
} else if (wasActive || wasNearActive) {
68+
runOnJS(setFocused)(false);
69+
}
70+
},
71+
[currentPage]);
5772

5873
const animatedPageStyle = useAnimatedStyle(() => {
5974
const isActive = Math.round(currentPage.value) === index;
@@ -70,7 +85,8 @@ export default function TabPage({
7085
return (
7186
<Reanimated.View style={style} testID={testID}>
7287
{!shouldLoad && renderLoading?.()}
73-
{shouldLoad && props.children}
88+
{/* {shouldLoad && props.children} */}
89+
<Freeze freeze={!shouldLoad || !focused}>{props.children}</Freeze>
7490
</Reanimated.View>
7591
);
7692
}

0 commit comments

Comments
 (0)