【问题标题】:React Native Expo - Custom Fonts Not Loading With Font.loadAsyncReact Native Expo - 自定义字体未使用 Font.loadAsync 加载
【发布时间】:2021-10-04 18:03:32
【问题描述】:

我了解最新的 Expo 版本,但由于某种原因,我无法获得简单的自定义字体。这是我设置的一个新项目,试图安装自定义字体。

import React, { useState } from 'react';
import { Text, View } from 'react-native';
import AppLoading from 'expo-app-loading';
import * as Font from 'expo-font';

const fetchFonts = () =>
  Font.loadAsync({
    'Inter-Black': require('./assets/fonts/Inter-Black.otf'),
  });

export default (props) => {
  const [dataLoaded, setDataLoaded] = useState(false);

  if (!dataLoaded) {
    return (
      <AppLoading
        startAsync={fetchFonts}
        onFinish={() => setDataLoaded(true)}
        onError={(err) => console.log(err)}
      />
    );
  }

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text style={{ fontFamily: 'Inter-Black', fontSize: 40 }}>
        Inter Black
      </Text>
      <Text style={{ fontSize: 40 }}>Platform Default</Text>
    </View>
  );
};

这是我在控制台中得到的:

fontFamily "Inter-Black" is not a system font and has not been loaded through Font.loadAsync.

- If you intended to use a system font, make sure you typed the name correctly and that it is supported by your device operating system.

- If this is a custom font, be sure to load it with Font.loadAsync.
at node_modules/expo-font/build/Font.js:27:16 in processFontFamily
at [native code]:null in performSyncWorkOnRoot
at [native code]:null in dispatchAction
at App.js:19:37 in AppLoading.props.onFinish
at node_modules/expo-app-loading/build/AppLoading.js:41:12 in startLoadingAppResourcesAsync
at [native code]:null in flushedQueue
at [native code]:null in invokeCallbackAndReturnFlushedQueue

【问题讨论】:

    标签: javascript react-native mobile fonts expo


    【解决方案1】:

    您必须等待加载功能

    const fetchFonts = async () =>
      await Font.loadAsync({
        'Inter-Black': require('./assets/fonts/Inter-Black.otf'),
      });
    

    另外,请尝试创建一个自定义挂钩来加载字体。检查this答案。

    你可以这样做

    在您的App.js 所在的位置创建一个名为hooks 的文件夹。然后在hooks文件夹中创建一个名为useFonts.js的文件

    useFonts.js里面这样写

    import * as Font from "expo-font";
     
    export default useFonts = async () =>
      await Font.loadAsync({
        'Inter-Black': require('./assets/fonts/Inter-Black.otf'),
      });
    

    现在在您的App.js 中这样写

    import * as Font from 'expo-font';
    import AppLoading from 'expo-app-loading';
    import React, { useState } from 'react';
    
    import useFonts from './hooks/useFonts';
    
    export default function App() {
      const [IsReady, SetIsReady] = useState(false);
    
      const LoadFonts = async () => {
        await useFonts();
      };
    
      if (!IsReady) {
        return (
          <AppLoading
            startAsync={LoadFonts}
            onFinish={() => SetIsReady(true)}
            onError={() => {}}
          />
        );
      }
    
      return <View styles={styles.container}>{/* Code Here */}</View>;
    }
    

    【讨论】:

    • 我得到:错误:渲染的钩子比上一次渲染时更多。因为onFinish={() =&gt; SetIsReady(true)},如果我从调用中删除SetIsReady(true)(例如:onFinish={() =&gt; {}),将不会调用错误,但应用程序也不会加载!怎么解决?
    • 是的,除非您没有将状态 IsReady 设置为 true,否则它将向您显示 AppLoading 组件,因此您的应用程序不会加载。 Here's 执行字体加载操作的零食。希望这会有所帮助。
    • 顺便说一句,我创建了一个新项目,您建议的代码运行良好。然而,通过引入一个新的 useState const 会引发同样的错误!错误:比上一次渲染时渲染的钩子更多。
    • 终于找到问题的根源了!问题是我在这段代码下面有一些useStateuseRef 常量:if (!IsReady) { return ( &lt;AppLoading startAsync={LoadFonts} .../&gt;);} 通过简单地将我的useStateuseRef 常量移动到这段代码上面,现在代码工作得很好。我猜问题是这些钩子在第一次渲染中无法访问,但是一旦 IsReady 为真,它们就可以访问,因此,错误:Error: Rendered more hooks than during the previous render
    猜你喜欢
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 2022-06-17
    • 1970-01-01
    相关资源
    最近更新 更多