Skip to content

Commit d9b64aa

Browse files
committed
fix: remove async local storage and splashscreen prevent auto hide
1 parent f072c3d commit d9b64aa

File tree

8 files changed

+71
-137
lines changed

8 files changed

+71
-137
lines changed

apps/docs/src/content/docs/getting-started/initial-setup.mdx

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,14 @@ Follow the installation guide for NativeWind from the <a target="_blank" href="
166166
**Platforms:** Web, iOS, and Android
167167

168168
```bash
169-
npx expo install tailwindcss-animate @react-native-async-storage/async-storage class-variance-authority clsx tailwind-merge
169+
npx expo install tailwindcss-animate class-variance-authority clsx tailwind-merge
170170
```
171171
</TabItem>
172172
<TabItem label="Native only">
173173
**Platforms:** iOS and Android
174174

175175
```bash
176-
npx expo install @react-native-async-storage/async-storage class-variance-authority clsx tailwind-merge
176+
npx expo install class-variance-authority clsx tailwind-merge
177177
```
178178
</TabItem>
179179
</Tabs>
@@ -361,9 +361,8 @@ and store the selected theme in the async storage.
361361
code={`
362362
import '~/global.css';
363363
364-
import AsyncStorage from '@react-native-async-storage/async-storage';
365364
import { Theme, ThemeProvider } from '@react-navigation/native';
366-
import { SplashScreen, Stack } from 'expo-router';
365+
import { Stack } from 'expo-router';
367366
import { StatusBar } from 'expo-status-bar';
368367
import * as React from 'react';
369368
import { Platform } from 'react-native';
@@ -384,36 +383,22 @@ export {
384383
ErrorBoundary,
385384
} from 'expo-router';
386385
387-
// Prevent the splash screen from auto-hiding before getting the color scheme.
388-
SplashScreen.preventAutoHideAsync();
389-
390386
export default function RootLayout() {
391-
const { colorScheme, setColorScheme, isDarkColorScheme } = useColorScheme();
387+
const hasMounted = React.useRef(false);
388+
const { colorScheme, isDarkColorScheme } = useColorScheme();
392389
const [isColorSchemeLoaded, setIsColorSchemeLoaded] = React.useState(false);
393390
394-
React.useEffect(() => {
395-
(async () => {
396-
const theme = await AsyncStorage.getItem('theme');
397-
if (Platform.OS === 'web') {
398-
// Adds the background color to the html element to prevent white background on overscroll.
399-
document.documentElement.classList.add('bg-background');
400-
}
401-
if (!theme) {
402-
AsyncStorage.setItem('theme', colorScheme);
403-
setIsColorSchemeLoaded(true);
404-
return;
405-
}
406-
const colorTheme = theme === 'dark' ? 'dark' : 'light';
407-
if (colorTheme !== colorScheme) {
408-
setColorScheme(colorTheme);
409-
410-
setIsColorSchemeLoaded(true);
411-
return;
412-
}
413-
setIsColorSchemeLoaded(true);
414-
})().finally(() => {
415-
SplashScreen.hideAsync();
416-
});
391+
useIsomorphicLayoutEffect(() => {
392+
if (hasMounted.current) {
393+
return;
394+
}
395+
396+
if (Platform.OS === 'web') {
397+
// Adds the background color to the html element to prevent white background on overscroll.
398+
document.documentElement.classList.add('bg-background');
399+
}
400+
setIsColorSchemeLoaded(true);
401+
hasMounted.current = true;
417402
}, []);
418403
419404
if (!isColorSchemeLoaded) {
@@ -427,6 +412,10 @@ export default function RootLayout() {
427412
</ThemeProvider>
428413
);
429414
}
415+
416+
const useIsomorphicLayoutEffect =
417+
Platform.OS === 'web' && typeof window === 'undefined' ? React.useEffect : React.useLayoutEffect;
418+
430419
`} />
431420

432421
### Install and Set Up Icons

apps/showcase/app/_layout.tsx

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
2-
import AsyncStorage from '@react-native-async-storage/async-storage';
32
import { Theme, ThemeProvider, DefaultTheme, DarkTheme } from '@react-navigation/native';
43
import { PortalHost } from '@rn-primitives/portal';
54
import { DeprecatedUi } from '@rnr/reusables';
6-
import { SplashScreen, Stack } from 'expo-router';
5+
import { Stack } from 'expo-router';
76
import { StatusBar } from 'expo-status-bar';
87
import * as React from 'react';
98
import { Platform } from 'react-native';
@@ -35,38 +34,23 @@ export const unstable_settings = {
3534
initialRouteName: '(tabs)',
3635
};
3736

38-
// Prevent the splash screen from auto-hiding before getting the color scheme.
39-
SplashScreen.preventAutoHideAsync();
40-
4137
export default function RootLayout() {
42-
const { colorScheme, setColorScheme, isDarkColorScheme } = useColorScheme();
38+
const hasMounted = React.useRef(false);
39+
const { colorScheme, isDarkColorScheme } = useColorScheme();
4340
const [isColorSchemeLoaded, setIsColorSchemeLoaded] = React.useState(false);
4441

45-
React.useEffect(() => {
46-
(async () => {
47-
const theme = await AsyncStorage.getItem('theme');
48-
if (Platform.OS === 'web') {
49-
// Adds the background color to the html element to prevent white background on overscroll.
50-
document.documentElement.classList.add('bg-background');
51-
}
52-
if (!theme) {
53-
setAndroidNavigationBar(colorScheme);
54-
AsyncStorage.setItem('theme', colorScheme);
55-
setIsColorSchemeLoaded(true);
56-
return;
57-
}
58-
const colorTheme = theme === 'dark' ? 'dark' : 'light';
59-
setAndroidNavigationBar(colorTheme);
60-
if (colorTheme !== colorScheme) {
61-
setColorScheme(colorTheme);
42+
useIsomorphicLayoutEffect(() => {
43+
if (hasMounted.current) {
44+
return;
45+
}
6246

63-
setIsColorSchemeLoaded(true);
64-
return;
65-
}
66-
setIsColorSchemeLoaded(true);
67-
})().finally(() => {
68-
SplashScreen.hideAsync();
69-
});
47+
if (Platform.OS === 'web') {
48+
// Adds the background color to the html element to prevent white background on overscroll.
49+
document.documentElement.classList.add('bg-background');
50+
}
51+
setAndroidNavigationBar(colorScheme);
52+
setIsColorSchemeLoaded(true);
53+
hasMounted.current = true;
7054
}, []);
7155

7256
if (!isColorSchemeLoaded) {
@@ -111,6 +95,9 @@ export default function RootLayout() {
11195
);
11296
}
11397

98+
const useIsomorphicLayoutEffect =
99+
Platform.OS === 'web' && typeof window === 'undefined' ? React.useEffect : React.useLayoutEffect;
100+
114101
function toOptions(name: string) {
115102
const title = name
116103
.split('-')

apps/showcase/components/ThemeToggle.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import AsyncStorage from '@react-native-async-storage/async-storage';
21
import { Pressable, View } from 'react-native';
32
import { setAndroidNavigationBar } from '~/lib/android-navigation-bar';
43
import { MoonStar } from '~/lib/icons/MoonStar';
@@ -8,14 +7,16 @@ import { cn } from '~/lib/utils';
87

98
export function ThemeToggle() {
109
const { isDarkColorScheme, setColorScheme } = useColorScheme();
10+
11+
function toggleColorScheme() {
12+
const newTheme = isDarkColorScheme ? 'light' : 'dark';
13+
setColorScheme(newTheme);
14+
setAndroidNavigationBar(newTheme);
15+
}
16+
1117
return (
1218
<Pressable
13-
onPress={() => {
14-
const newTheme = isDarkColorScheme ? 'light' : 'dark';
15-
setColorScheme(newTheme);
16-
setAndroidNavigationBar(newTheme);
17-
AsyncStorage.setItem('theme', newTheme);
18-
}}
19+
onPress={toggleColorScheme}
1920
className='web:ring-offset-background web:transition-colors web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2'
2021
>
2122
{({ pressed }) => (

apps/showcase/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
"dependencies": {
1717
"@gorhom/bottom-sheet": "^4.6.0",
1818
"@hookform/resolvers": "^3.3.4",
19-
"@react-native-async-storage/async-storage": "1.23.1",
2019
"@react-native-community/slider": "4.5.5",
2120
"@react-navigation/material-top-tabs": "^7.0.0",
2221
"@react-navigation/native": "^7.0.0",

packages/templates/starter-base/app/_layout.tsx

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import '~/global.css';
22

3-
import AsyncStorage from '@react-native-async-storage/async-storage';
43
import { DarkTheme, DefaultTheme, Theme, ThemeProvider } from '@react-navigation/native';
5-
import { SplashScreen, Stack } from 'expo-router';
4+
import { Stack } from 'expo-router';
65
import { StatusBar } from 'expo-status-bar';
76
import * as React from 'react';
87
import { Platform } from 'react-native';
@@ -26,37 +25,23 @@ export {
2625
ErrorBoundary,
2726
} from 'expo-router';
2827

29-
// Prevent the splash screen from auto-hiding before getting the color scheme.
30-
SplashScreen.preventAutoHideAsync();
31-
3228
export default function RootLayout() {
33-
const { colorScheme, setColorScheme, isDarkColorScheme } = useColorScheme();
29+
const hasMounted = React.useRef(false);
30+
const { colorScheme, isDarkColorScheme } = useColorScheme();
3431
const [isColorSchemeLoaded, setIsColorSchemeLoaded] = React.useState(false);
3532

36-
React.useEffect(() => {
37-
(async () => {
38-
const theme = await AsyncStorage.getItem('theme');
39-
if (Platform.OS === 'web') {
40-
// Adds the background color to the html element to prevent white background on overscroll.
41-
document.documentElement.classList.add('bg-background');
42-
}
43-
if (!theme) {
44-
AsyncStorage.setItem('theme', colorScheme);
45-
setIsColorSchemeLoaded(true);
46-
return;
47-
}
48-
const colorTheme = theme === 'dark' ? 'dark' : 'light';
49-
if (colorTheme !== colorScheme) {
50-
setColorScheme(colorTheme);
51-
setAndroidNavigationBar(colorTheme);
52-
setIsColorSchemeLoaded(true);
53-
return;
54-
}
55-
setAndroidNavigationBar(colorTheme);
56-
setIsColorSchemeLoaded(true);
57-
})().finally(() => {
58-
SplashScreen.hideAsync();
59-
});
33+
useIsomorphicLayoutEffect(() => {
34+
if (hasMounted.current) {
35+
return;
36+
}
37+
38+
if (Platform.OS === 'web') {
39+
// Adds the background color to the html element to prevent white background on overscroll.
40+
document.documentElement.classList.add('bg-background');
41+
}
42+
setAndroidNavigationBar(colorScheme);
43+
setIsColorSchemeLoaded(true);
44+
hasMounted.current = true;
6045
}, []);
6146

6247
if (!isColorSchemeLoaded) {
@@ -79,3 +64,6 @@ export default function RootLayout() {
7964
</ThemeProvider>
8065
);
8166
}
67+
68+
const useIsomorphicLayoutEffect =
69+
Platform.OS === 'web' && typeof window === 'undefined' ? React.useEffect : React.useLayoutEffect;

packages/templates/starter-base/components/ThemeToggle.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import AsyncStorage from '@react-native-async-storage/async-storage';
21
import { Pressable, View } from 'react-native';
32
import { setAndroidNavigationBar } from '~/lib/android-navigation-bar';
43
import { MoonStar } from '~/lib/icons/MoonStar';
@@ -8,14 +7,16 @@ import { cn } from '~/lib/utils';
87

98
export function ThemeToggle() {
109
const { isDarkColorScheme, setColorScheme } = useColorScheme();
10+
11+
function toggleColorScheme() {
12+
const newTheme = isDarkColorScheme ? 'light' : 'dark';
13+
setColorScheme(newTheme);
14+
setAndroidNavigationBar(newTheme);
15+
}
16+
1117
return (
1218
<Pressable
13-
onPress={() => {
14-
const newTheme = isDarkColorScheme ? 'light' : 'dark';
15-
setColorScheme(newTheme);
16-
setAndroidNavigationBar(newTheme);
17-
AsyncStorage.setItem('theme', newTheme);
18-
}}
19+
onPress={toggleColorScheme}
1920
className='web:ring-offset-background web:transition-colors web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2'
2021
>
2122
{({ pressed }) => (

packages/templates/starter-base/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
"postinstall": "npx tailwindcss -i ./global.css -o ./node_modules/.cache/nativewind/global.css"
1414
},
1515
"dependencies": {
16-
"@react-native-async-storage/async-storage": "1.23.1",
1716
"@react-navigation/native": "^7.0.0",
1817
"@rn-primitives/avatar": "~1.1.0",
1918
"@rn-primitives/portal": "~1.1.0",

pnpm-lock.yaml

Lines changed: 0 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)