본문 바로가기

React + React Native + Expo

[React Native Expo] Font 전체 컴포넌트 폰트 변경 / default font

반응형

 

1. 폰트 다운 

https://www.woowahan.com/#/

 

우아한형제들

좋은 음식을 먹고 싶은 곳에서~! 우아한 사람들이 모여 우와하게 일하는 '우아한형제들'입니다.

www.woowahan.com

 

 

 

2. expo-font 설치 

npm install expo-font

 

 

3. assets 폴더 > fonts 폴더 > 에 다운 받은 폰트 넣기 

 

4. config.json 추가 수정

  "rnpm": {
    "assets": [
      "./assets/fonts"
    ]
  },

 

 

 

5. Text 에 폰트를 담아 return 할  component 생성 

'use strict'

import React, { useEffect, useState } from 'react';
import { Text } from 'react-native'
import * as Font from 'expo-font';

// custum font 설정 component
const DefaultText = ({ children, style }) => {
    const [fontLoad, setFontLoad] = useState(false)

    // font 불러오기 
    useEffect(() => {
        Font.loadAsync({
            'BMHANNA_11yrs': require('../assets/fonts/BMHANNA_11yrs.ttf')
        })
        setFontLoad(true)
    }, [])

    // 배열 형식으로 폰트 fontStyle 변수에 담기 
    let fontStyle = [{ fontFamily: 'BMHANNA_11yrs' }]
    if (style) {
        // style 이 Array 라면 concat으로 합치기 
        if (Array.isArray(style)) {
            fontStyle = fontStyle.concat(style)
        } else {
            // Array가 아니라면 push하기 
            fontStyle.push(style)
        }
    }

    return (
        <Text style={fontStyle}>
            {children}
        </Text>
    )
}

export default DefaultText

 

 

 

 

6. 해당 폰트를 사용할 component에서 불러오기 / Text from 'react-native' 는 삭제 

import Text from './DefaultText';

 

 

 

=> 요렇게 하니까 font loading 이전에 폰트가 있는 text를 쓸 수 없다고 오류가 나옴 ! 

 

최상위 컴포넌트 App.js 에 로딩을 해주고 

import 'react-native-gesture-handler';
import React, { useEffect, useState } from 'react';
import { Text, View, StyleSheet } from 'react-native';
// import * as SplashScreen from 'expo-splash-screen';
// import Splash from './screens/Splash';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import MainApp from './navigators/MainApp';
import Login from './screens/Login';
import Auth from './screens/Auth';
import Main from './screens/Main';;
import Signup from './screens/Signup';
import Welcome from './screens/Welcome';
import * as Font from 'expo-font';

// 구조 변경 RootApp == App 에서 Tab의 여부로 Components 구별 
const App = () => {
  
  const [fontLoad, setFontLoad] = useState(false)
  const AppStack = createNativeStackNavigator();

  // font 불러오기
  useEffect(() => {
    const Load=async()=>{
      await Font.loadAsync({
          'BMHANNA_11yrs': require('./assets/fonts/BMHANNA_11yrs.ttf'),
          'BMEULJIROTTF': require('./assets/fonts/BMEULJIROTTF.ttf')
      })
      setFontLoad(true)
    }
    Load()
  }, [])

  // font Loading 여부에 따라 return 
  return (
    fontLoad ? 
    <NavigationContainer>
      <AppStack.Navigator screenOptions={{ headerShown: false, }}>
        {/* BottomTAB 없는 Screen   */}
        <AppStack.Screen name="Auth" component={Auth} />
        <AppStack.Screen name="Main" component={Main} />
        <AppStack.Screen name="Login" component={Login} />
        <AppStack.Screen name="Signup" component={Signup} />
        <AppStack.Screen name="Welcome" component={Welcome} />
        {/* BottomTAB 있는 Screen  */}
        <AppStack.Screen name="MainApp" component={MainApp} />
        {/* // options ={{headerTintColor: primary }} better not have for iOS or at least for the current pic */}
      </AppStack.Navigator>
    </NavigationContainer>
    :
    <View style={styles.appLoading}>
      <Text>
        Loading...
      </Text>
    </View>
  )
}

// ' Loading...' 중앙 정렬 
const styles = StyleSheet.create({
  appLoading:{
    flex:1,
    justifyContent:'center',
    alignItems:'center',
  }
})

export default App

 

DefaultText 는 아래처럼 수정 

'use strict'

import React, { useEffect, useState } from 'react';
import { Text } from 'react-native'
import * as Font from 'expo-font';

// custum font 설정 component 
const DefaultText = ({ children, style }) => {

    // 배열 형식으로 폰트 fontStyle 변수에 담기 
    let fontStyle = [{ fontFamily: 'BMHANNA_11yrs' }]
    if (style) {
        // style 이 Array 라면 concat으로 합치기 
        if (Array.isArray(style)) {
            fontStyle = fontStyle.concat(style)
        } else {
            // Array가 아니라면 push하기 
            fontStyle.push(style)
        }
    }

    return (
        
        <Text style={fontStyle} >
            {children}
        </Text>
    )
}

export default DefaultText

 

 

이렇게 하니 오류가 안뜬다 ! ! 

반응형