Expo SDK 45与React Navigation一起使用的启动画面

14

我刚刚升级到Expo SDK 45,收到了一个警告:“expo-app-loading已被弃用,建议使用expo-splash-screen: 使用SplashScreen.preventAutoHideAsync()和SplashScren.hideAsync()代替。https://docs.expo.dev/versions/latest/sdk/splash-screen/。所以我按照提供的链接去做了。

现在我的问题是,在示例中,他们在根视图的onLayOut上调用onLayOutRootView。现在我正在使用react-navigation,因此我的根视图嵌套在我的应用程序中很深。

我是否需要将此函数传递到根视图,还是有一种方法将此函数传递给我的任何其他提供商/导航容器?或者有其他解决方法吗?

//imports


export default App = () => {
  const [appIsReady, setAppIsReady] = useState(false);
  const scheme = "dark";

  useEffect(() => {
    async function prepare() {
      try {
        // Keep the splash screen visible while we fetch resources
        await SplashScreen.preventAutoHideAsync();
        // Pre-load fonts, make any API calls you need to do here
        await Font.loadAsync(customFonts);
      } catch (e) {
        console.warn(e);
      } finally {
        // Tell the application to render
        setAppIsReady(true);
      }
    }

    prepare();
  }, []);

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

  if (appIsReady) {
    return (
      <StripeProvider publishableKey={PUBLISHABLE_KEY}>
        <ThemeProvider theme={scheme === "dark" ? darkTheme : lightTheme}>
          <StatusBar barStyle={scheme === "dark" ? "light-content" : "dark-content"} />
          <OrderProvider>
            <CartProvider>
              <FavoriteProvider>
                <FirebaseProvider>
                  <UserProvider>
                    <NavigationContainer
                      theme={scheme === "dark" ? darkTheme : lightTheme}
                      ref={navigationRef}
                    >
                      <RootStackScreens on/>
                    </NavigationContainer>
                  </UserProvider>
                </FirebaseProvider>
              </FavoriteProvider>
            </CartProvider>
          </OrderProvider>
        </ThemeProvider>
      </StripeProvider>
    );
  } else {
    return null;
  }
};

谢谢。


嘿 Bert - 我也遇到了同样的问题哈哈,刚刚到达了 expo 45。我刚刚放弃了整个回调函数。我一直在收到“SplashScreen.show 已经被调用”的消息,只是将真正的返回值隐藏在 if isReady 后面。- 希望其他人有更好的贡献哈哈。 - snoop
标记的答案对我有效 :) - Bert Van Hecke
3个回答

18

由于问题使用了NavigationContainer,我认为最好的方法是遵循Expo的说明,但修改函数的'return',将onLayoutRootView传递给NavigationContainer而不是View,如下所示:

return (
...
  <NavigationContainer
    theme={scheme === "dark" ? darkTheme : lightTheme}
    ref={navigationRef}
    onReady={onLayoutRootView} // <-- HERE!
  >
     <RootStackScreens on/>
  </NavigationContainer>
...
)

本答案基于此代码示例


谢谢,运作得很顺利!我认为这应该是被接受的答案,因为它更符合导航包的预期使用方式和Expo的指示。 - buechel
确实,正如@buechel所说,这应该是正确的答案,因为它不包含额外的视图。谢谢! - undefined

17

你可以尝试将所有内容用flex:1包裹在一个 View 中。

像这样:

...imports...
import { View } from "react-native";
    
export default App = () => {

 ...code...

 const onLayoutRootView = useCallback(async () => {
  if (appIsReady) {
   await SplashScreen.hideAsync();
  }
 }, [appIsReady]);
    
 if (!appIsReady) {
  return null;
 }
    
 return (
  <View style={{ flex: 1 }} onLayout={onLayoutRootView}>
   <StripeProvider publishableKey={PUBLISHABLE_KEY}>
     ...
   </StripeProvider>
  </View>
 );
}

这似乎解决了问题!谢谢。 - Bert Van Hecke
奇怪,它确实移除了加载,但是应用程序根本没有加载或崩溃了 x) (使用expo-app-loading不会发生这种情况) - jave.web

6
只需在 onLayoutRootView 上调用 set NavigationContainer 的 onReady 方法。
 <NavigationContainer onReady={onLayoutRootView}>
    <NavigatorDrawer />
 </NavigationContainer>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接