Экспо шрифты в глобальной таблице стилей
Я использую 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
);
}
}