React Native & Expo,如何控制闪屏?

Oll*_*lie 7 javascript reactjs react-native expo

我正在使用博览会中的内置启动屏幕,您可以将其添加到app.json一个简单的测试应用程序中。但是我注意到我的开始屏幕在显示我添加的资源之前以默认模式闪烁 1 毫秒AsyncStorage

我尝试过使用世博会的启动画面包,但我发现它有点令人困惑。有没有一种相当简单的方法来添加我的App.js这个逻辑:

显示启动屏幕,当加载所有资源时,加载此设置(使用我的上下文和屏幕),或者只是增加博览会启动屏幕中构建的加载时间(因为我假设它会加载正在获取的资源?)。

const App = () => {

  const [selectedTheme, setSelectedTheme] = useState(themes.light)

  const changeTheme = async () =>{
    try {
      const theme = await AsyncStorage.getItem("MyTheme")
      if (theme === "dark"){
      setSelectedTheme(themes.nightSky)} 
      else if (theme === "light") {
        setSelectedTheme(themes.arctic)
        }
    } catch (err) {alert(err)}
  }
  
  useEffect(()=> {
    changeTheme()
  },[])


  return (
    <ThemeContext.Provider value={{selectedTheme, changeTheme}}>
         <NavigationContainer>
            <Stack.Navigator screenOptions={{headerShown:false, presentation: 'modal'}}>
              <Stack.Screen name="Home" component={home}/>
            </Stack.Navigator>
          </NavigationContainer>
    </ThemeContext.Provider>

  );
};
Run Code Online (Sandbox Code Playgroud)

You*_*mar 4

第一个解决方案

您可以使用Expo 的SplashScreen模块。以下是如何使用它的概述:

expo install expo-splash-screen
Run Code Online (Sandbox Code Playgroud)
import * as SplashScreen from "expo-splash-screen";
import React, { useCallback, useEffect, useState } from "react";
import { Text, View } from "react-native";

export default function App() {
  const [appIsReady, setAppIsReady] = useState(false);

  useEffect(() => {
    async function prepare() {
      // Keep the splash screen visible
      await SplashScreen.preventAutoHideAsync();
      // Do what you need before the splash screen gets hidden
      console.log("I'm a task that gets executed before splash screen disappears");
      // Then tell the application to render
      setAppIsReady(true);
    }
    prepare();
  }, []);

  const onLayoutRootView = useCallback(async () => {
    if (appIsReady) {
      // Hide the splash screen
      await SplashScreen.hideAsync();
    }
  }, [appIsReady]);

  if (!appIsReady) {
    return null;
  }

  return (
    <View onLayout={onLayoutRootView} style={{ flex: 1, justifyContent: "center", alignItems: "center" }}><Text>Hello Word!</Text> </View>
  );
}
Run Code Online (Sandbox Code Playgroud)

第二种解决方案

还有来自 Expo 的AppLoading组件,但它似乎已被弃用。但它确实有效,这里概述了如何使用它:

 expo install expo-app-loading
Run Code Online (Sandbox Code Playgroud)
expo install expo-splash-screen
Run Code Online (Sandbox Code Playgroud)

额外一张

下面的部分是一个使用AppLoading回答上述问题的特殊用例:

import * as SplashScreen from "expo-splash-screen";
import React, { useCallback, useEffect, useState } from "react";
import { Text, View } from "react-native";

export default function App() {
  const [appIsReady, setAppIsReady] = useState(false);

  useEffect(() => {
    async function prepare() {
      // Keep the splash screen visible
      await SplashScreen.preventAutoHideAsync();
      // Do what you need before the splash screen gets hidden
      console.log("I'm a task that gets executed before splash screen disappears");
      // Then tell the application to render
      setAppIsReady(true);
    }
    prepare();
  }, []);

  const onLayoutRootView = useCallback(async () => {
    if (appIsReady) {
      // Hide the splash screen
      await SplashScreen.hideAsync();
    }
  }, [appIsReady]);

  if (!appIsReady) {
    return null;
  }

  return (
    <View onLayout={onLayoutRootView} style={{ flex: 1, justifyContent: "center", alignItems: "center" }}><Text>Hello Word!</Text> </View>
  );
}
Run Code Online (Sandbox Code Playgroud)