Экспо шрифты в глобальной таблице стилей

Я использую Expo и мне нужно использовать пользовательские шрифты в моей глобальной таблице стилей. Экспо документирует это, однако в моем случае это не актуально, так как componentDidMount() выполняется только внутри класса:

class App extends React.Component {
  componentDidMount() {
    Font.loadAsync({
      'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf'),
    });
  }

  // ...
}

Моя глобальная таблица стилей выглядит так:

const React = require('react-native');

import {
  Dimensions,
  StatusBar,
} from 'react-native';

const { StyleSheet } = React;

export default {
  // ...
}

3 ответа

Загрузка шрифтов в Expo является "ленивой" в том смысле, что вы можете создать объект StyleSheet, который ссылается на шрифт до его загрузки. Например, этот код действителен:

async function exampleAsync() {
  let stylesheet = StyleSheet.create({
    fancyText: {
      ...Expo.Font.style('open-sans-bold'),
    },
  });

  await Expo.Font.loadAsync({
    'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf'),
  });
}

Так что вам не нужно звонить Expo.Font.loadAsync в componentDidMount обязательно, и это нормально, чтобы позвонить StyleSheet.create а также Expo.Font.style перед загрузкой шрифта.

Важно то, что вы ждете Expo.Font.loadAsync завершить перед рендерингом компонента, стиль которого использует загруженный шрифт.

В итоге я просто загрузил шрифты в файл навигации, а затем смог получить доступ к этим шрифтам в моей глобальной таблице стилей и во всем приложении.

Что вы можете сделать, это просто добавить в корневой / верхний компонент флаг состояния, проверяющий, закончена ли уже асинхронность шрифта.

Затем добавьте условие в ваш метод рендеринга, чтобы быть уверенным, что ваши дочерние компоненты будут отображаться только после успешной загрузки шрифтов. Пожалуйста, смотрите пример

     export default class App extends React.Component {
      state = {
        fontLoaded: false,
      }

      componentDidMount() {
        this.loadAssetsAsync();
      }

      async loadAssetsAsync() {
        await Expo.Font.loadAsync({
         'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf'),
        });;

        this.setState({ fontLoaded: true });
      }

      render() {
        if (!this.state.fontLoaded) {
          return <AppLoading />;  // render some progress indicator
        }

        return (
          <Navigator />    //render your child components tree
        );
      }
    }
Другие вопросы по тегам