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

React Native+Expo+TWRNC自定义字体与Tailwind配置问题求助

问题

使用React Native、Expo、expo-google-fonts和TWRNC开发时遇到两个核心问题:

  1. 已在根目录_layout.tsx中配置自定义字体,但字体未生效(其他样式可正常应用)
  2. TWRNC无法识别tailwind.config.js中theme.extend内新增的属性,使用时提示「未知或错误的工具类」

已完成的操作:

  • 将自定义字体放入assets/fonts目录
  • 在_layout.tsx中配置加载字体
  • 确保tailwind.config.js配置项完整

附用户提供的相关代码:

//tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {
      colors: {
        "error-color": "#F50A00"
      },
      fontFamily: {
        "openSansRegular": ["OpenSans_400Regular"],
        "openSansMedium": ["OpenSans_500Medium"],
        "openSansSemiBold": ["OpenSans_600SemiBold"],
        "openSansBold": ["OpenSans_700Bold"],
        "openSansExtraBold": ["OpenSans_800ExtraBold"],
      }
    },
  },
  plugins: [],
};
//_layout.tsx global
import { Stack, SplashScreen, Slot } from "expo-router";
import {
  useFonts,
  OpenSans_400Regular,
  OpenSans_500Medium,
  OpenSans_600SemiBold,
  OpenSans_700Bold,
  OpenSans_800ExtraBold,
} from "@expo-google-fonts/open-sans";
import { useEffect } from "react";

SplashScreen.preventAutoHideAsync();

const RootLayout = () => {
  const [fontLoaded, fonError] = useFonts({
    OpenSans_400Regular,
    OpenSans_500Medium,
    OpenSans_600SemiBold,
    OpenSans_700Bold,
    OpenSans_800ExtraBold,
  });

  useEffect(() => {
    if (fontLoaded || fonError) {
      //* Delay de 2s para ocultar a Splash Screen e iniciar a navegação
      setTimeout(async () => {
        await SplashScreen.hideAsync();
      }, 2000);
    }
  }, [fontLoaded, fonError]);

  if (!fontLoaded && !fonError) {
    return null;
  }

  return (
    <>
      {/* <Slot /> */}
      <Stack screenOptions={{ headerShown: false }} />
        {/* <Stack.Screen name="login" />
        <Stack.Screen name="register" />
      </Stack> */}
    </>
  );
};

export default RootLayout
//Component that uses the font
import { StatusBar } from "expo-status-bar"
import { View, Text } from "react-native"
import tw from "twrnc"
import { Footer } from "../../components/Footer"
import { GlobalTextFont } from "../../components/TextGlobalFont"
import { Button } from "react-native"
import { Link } from "expo-router"


const LoginScreen = (): React.JSX.Element => {
  return (
    <>
      <View style={tw `bg-neutral-800 flex-1 items-center justify-center p-3`}>
        <Text style={tw `font-openSansBold text-xl text-neutral-100 text-error-color`}>Tela de login</Text>
        <Text style={tw `text-neutral-100 font-medium text-lg`}>Deus me deu inteligência e usando a fé eu digo que sou capaz porque Deus me faz capaz de renderizar o formulário</Text>
        <StatusBar style="light"/>
      <Link style={tw `text-lg text-neutral-100 mt-2`} href="/register">Ir para cadastro</Link>
      </View>
      <Footer />
    </>
      
  )
}

export default LoginScreen

解决建议

一、修复TWRNC不识别tailwind.config.js的问题

TWRNC不会自动读取项目根目录的配置文件,需手动初始化并传入自定义配置:

  1. 创建自定义TWRNC实例文件,比如src/utils/tailwind.ts:
import twrnc from 'twrnc';
import tailwindConfig from '../../tailwind.config';

// 传入配置初始化实例
const tw = twrnc.create(tailwindConfig);

export default tw;
  1. 在所有使用TWRNC的组件中,替换默认导入为自定义实例:
// 替换原代码的 import tw from "twrnc"
import tw from '../utils/tailwind';

二、修复自定义字体不生效的问题

结合代码细节,需调整以下几点:

  1. 修正_layout.tsx的布局结构
    原代码注释掉了<Slot />和Stack子路由配置,导致子页面无法正常渲染,恢复正确的Expo Router布局写法:
return (
  <Stack screenOptions={{ headerShown: false }}>
    <Stack.Screen name="login" />
    <Stack.Screen name="register" />
  </Stack>
);
  1. 修复字体加载的拼写错误
    原代码中fonError为拼写错误,修正为fontError,避免字体加载异常无法被捕获:
const [fontLoaded, fontError] = useFonts({
  OpenSans_400Regular,
  OpenSans_500Medium,
  OpenSans_600SemiBold,
  OpenSans_700Bold,
  OpenSans_800ExtraBold,
});

useEffect(() => {
  if (fontLoaded || fontError) {
    setTimeout(async () => {
      await SplashScreen.hideAsync();
    }, 2000);
  }
}, [fontLoaded, fontError]);

if (!fontLoaded && !fontError) {
  return null;
}
  1. 完善tailwind字体族配置
    为每个自定义字体添加备用字体,避免加载失败时无 fallback:
fontFamily: {
  "openSansRegular": ["OpenSans_400Regular", "sans-serif"],
  "openSansMedium": ["OpenSans_500Medium", "sans-serif"],
  "openSansSemiBold": ["OpenSans_600SemiBold", "sans-serif"],
  "openSansBold": ["OpenSans_700Bold", "sans-serif"],
  "openSansExtraBold": ["OpenSans_800ExtraBold", "sans-serif"],
}

额外检查项

  • 确认依赖安装完整:执行npm install @expo-google-fonts/open-sans expo-font
  • 清除Expo缓存:运行npx expo start --clear,避免缓存导致的字体加载异常
  • 移除组件中冲突的样式类:比如LoginScreen中text-neutral-100和text-error-color不可同时使用,仅保留需要的颜色类

内容的提问来源于stack exchange,提问作者Isaias C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 23:32:06