expo / router

[ARCHIVE]: Expo Router has moved to expo/expo -- The File-based router for universal React Native apps

Home Page:https://docs.expo.dev/routing/introduction/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

White flash / flickering when using expo-font

Thanaen opened this issue · comments

Which package manager are you using? (Yarn is recommended)

npm

Summary

I’m developing an application with a dark and a light theme, and custom fonts.
I’m trying to migrate everything to expo, but I have a problem: I get a white flash when I launch my application.
I did a lot of research to find out what was causing this, and concluded that using expo’s useFont hook could cause the problem.

One solution would be to give a value to the “backgroundColor” property, in the app.json file, but this isn’t a good solution for two reasons:

  • only one color can be set, and therefore cannot be adapted to the dark theme (unless you use expo-system-ui with the setBackgroundColor method)
  • setting a backgroundColor has a very ugly effect on iOS modals, so it’s best to leave this property undefined.

I’m a bit up against the wall with this problem :(.

Minimal reproducible example

https://github.com/Thanaen/expo-router-font-white-flash

PS: I've also created a forum post for this issue

Any luck?

I haven't managed to solve the problem yet.

I've tried loading my fonts differently (via this library https://github.com/EvanBacon/link-native-assets-expo-config-plugin), but I've run into another bug that causes one of my custom fonts not to load on iOS. :(

Do you use the expo-splash-screen functions in your app? The docs reference using the package to prevent a white flash with expo-router: https://docs.expo.dev/routing/appearance/#fonts

This seems to help on the small repro project I've set up, but on my bigger project it doesn't prevent white flash :(

any update @Thanaen? we're facing the same issue :-(

Duplicate #675

Some notes about this issue (for future reference):

  1. The issue was that useFont (or any hook) would cause a re-render of the layout route, which would unmount the <SplashScreen /> component, and therefore hide the splash screen prematurely. This SplashScreen-component API was flawed which is why it's been deprecated.
  2. Not using the SplashScreen component fixes the issue because the default hiding works.
  3. Alternatively, you can prevent hiding by modifying the root layout file to use the new API. You will need to delay hiding by a frame though:
import { SplashScreen, Stack } from "expo-router";

SplashScreen.preventAutoHideAsync();

const Layout = () => {
  const colorScheme = useColorScheme();
  let [fontsLoaded] = useFonts({
    Inter_900Black,
  });

  React.useEffect(() => {
    if (fontsLoaded) {
      setTimeout(() => {
        SplashScreen.hideAsync();
      });
    }
  }, [fontsLoaded]);

  return (
    <ThemeProvider
      value={colorScheme === "dark" ? NavDarkTheme : NavDefaultTheme}
    >
      {fontsLoaded ? (
        <Stack>
         ...
        </Stack>
      ) : null}
    </ThemeProvider>
  );
};

export default Layout;

I've tested all of these locally and can personally confirm they work.

Thank you for your reply. I'll try the setTimeout trick!

@VirenMohindra
To be honest, I've paused the migration to expo-router for now, as I've encountered regressions related to the switch to expo-prebuild and expo-router that affect the UX. :/
I'll be opening other issues soon, as I fully intend to jump on the expo-prebuild and expo-router bandwagon!