Expo项目iOS模拟器启动报No native splash screen registered错误咨询
问题原因
这是expo-splash-screen的已知非阻断性问题,仅在iOS模拟器特定启动时序下触发,iOS物理机、Android端均不会复现,也不会影响线上版本功能,核心触发点是你的代码中SplashScreen.hideAsync()的调用时机早于原生闪屏视图控制器的注册完成时机:你当前直接在组件顶层调用onLayoutRootView(),没有绑定到根视图的onLayout回调上,当appIsReady状态更新后,调用隐藏闪屏的接口时,原生侧的闪屏实例还未完成注册或已经被销毁,就会抛出该警告。
修复方案
方案1(规范实现,彻底解决)
删除组件顶层直接调用的onLayoutRootView()语句,将该回调绑定到根视图的onLayout属性上,保证仅当根视图完成布局后再调用隐藏闪屏的接口,修改后的代码如下:
import React, { useState, useEffect, useCallback } from 'react'; import { View } from 'react-native'; import * as SplashScreen from 'expo-splash-screen'; import * as Font from 'expo-font'; import { Asset } from 'expo-asset'; import AppLoading from 'expo-app-loading'; import Navigation from './config/Navigation'; export default function App() { const [appIsReady, setAppIsReady] = useState(false); useEffect(() => { async function prepare() { try { await SplashScreen.preventAutoHideAsync(); await Asset.loadAsync(require('../assets/IMG_0024.jpg')); } catch (e) { console.warn(e); } finally { setAppIsReady(true); } } prepare(); }, []); const onLayoutRootView = useCallback(async () => { if (appIsReady) { await SplashScreen.hideAsync(); } }, [appIsReady]); if (!appIsReady) { return <AppLoading />; } // 给根View绑定onLayout回调 return ( <View style={{ flex: 1 }} onLayout={onLayoutRootView}> <Navigation /> </View> ); }
方案2(快速兼容,忽略非必要报错)
如果修改后仍偶现模拟器警告,可给hideAsync调用添加异常捕获,仅忽略该特定场景的错误即可,不会影响正常功能:
const onLayoutRootView = useCallback(async () => { if (appIsReady) { try { await SplashScreen.hideAsync(); } catch (e) { // 仅忽略闪屏未注册的非严重错误,其余错误仍上报 if (!e.message.includes('No native splash screen registered')) { console.warn(e); } } } }, [appIsReady]);
是否可以直接忽略
如果确认仅在iOS模拟器出现,所有物理设备运行正常、闪屏功能符合预期,可以直接忽略,该警告不会对线上版本产生任何影响。
内容的提问来源于stack exchange,提问作者brados
相关产品推荐
相关产品推荐

