You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native + Expo导入自定义字体时出现组件类型无效错误

React Native Expo导入自定义字体时出现组件类型无效错误

错误信息

Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s%s, undefined,  You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of `Layout`., 
    in Layout
    in Unknown (created by Route())
    in Route (created by Route())
    in LocationProvider (created by Route())
    in Route() (created by RootRoute)
    in RootRoute (created by ContextNavigator)
...

代码示例(_layout.js)

import { Stack, NavigationContainer } from 'expo-router';
import { useCallback } from 'react';
import { useFonts } from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';
import { Provider } from '../hook/context/auth';
import { LoginPage } from './(auth)/login';

SplashScreen.preventAutoHideAsync();

export default function Layout(){
    const [fontsLoaded] = useFonts({
        'DMBold': require('../assets/fonts/DMSans-Bold.ttf'),
        'DMMedium': require('../assets/fonts/DMSans-Medium.ttf'),
        'DMRegular': require('../assets/fonts/DMSans-Regular.ttf'),
    })

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

    if(!fontsLoaded){
        return null; // 加载启动屏
    }

    return (
    <Provider>
        <NavigationContainer>
            <Stack.Navigator onLayout={onLayoutRootView}>
                <Stack.Screen name="Login" component={LoginPage} />
            </Stack.Navigator>
        </NavigationContainer>
    </Provider>
    )
}

项目结构

项目结构截图

问题排查与解决方案

1. 检查自定义组件的导入导出匹配

错误核心是获取到undefined类型的组件,大概率是LoginPage或Provider的导入导出方式不匹配:

  • 针对LoginPage:
    若./(auth)/login.js中是默认导出(export default LoginPage),则导入时需去掉花括号:
    import LoginPage from './(auth)/login';
    
    若使用命名导出,确保login.js中的导出语句为:
    export function LoginPage() { /* 组件内容 */ }
    
  • 针对Provider:
    同理,检查../hook/context/auth.js中的Provider导出方式,默认导出则用import Provider from '../hook/context/auth';,命名导出需保持花括号导入且导出语句正确。

2. 移除冗余的NavigationContainer

Expo Router的Stack组件已内置导航容器,无需额外嵌套NavigationContainer,否则会引发导航上下文冲突。修改后的返回结构:

return (
  <Provider>
    <Stack.Navigator onLayout={onLayoutRootView}>
      <Stack.Screen name="Login" component={LoginPage} />
    </Stack.Navigator>
  </Provider>
)

3. 优化字体加载逻辑(可选)

可改用import方式导入字体,避免require可能的路径问题:

import DMBold from '../assets/fonts/DMSans-Bold.ttf';
import DMMedium from '../assets/fonts/DMSans-Medium.ttf';
import DMRegular from '../assets/fonts/DMSans-Regular.ttf';

const [fontsLoaded] = useFonts({
  'DMBold': DMBold,
  'DMMedium': DMMedium,
  'DMRegular': DMRegular,
})

内容的提问来源于stack exchange,提问作者code writer 3000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:55:10