성장, 그리고 노력

부족하더라도 어제보다 더 잘해지자. 노력은 절대 배신하지 않는다.

React

react-intl 적용하기

제이콥(JACOB) 2020. 1. 11. 03:25
이 글에서 사용한 코드(깃 저장소) - https://github.com/JungKyuHyun/react-intl-test

오랜만에 올리는 React 관련 포스팅. 

 최근 react-native 프로젝트에 react-intl을 적용하면서 찾아본 것들을 적어보려고 한다. 사실 이전에도 react를 이용하여 관리자 페이지를 만들었을 때도 react-intl을 적용하는 이슈를 할당받아 해결했었다. (TMI: Jira를 사용하고 회사라는 곳에서 받은 생애 첫 이슈여서, 평생 기억에 남을거 같다.)

 하여튼 react로 만든 웹이건, react-native로 만든 앱이건 둘다 사용 가능하다는 말을 하고 싶었다. 국제화라는 게 생각보다 어렵지 않으니 관련하여 참고하면 좋을 거 같다.


react-intl

 사실 이 라이브러리 말고 react-i18next도 고려해 봤으나, 여러 글들을 읽고 가장 일반적이고 더 많이 사용하는 react-intl로 결정했다. (react-intl vs react-i18next의 주제로도 여러 글들이 있으니, 궁금하다면 검색해보자.)

react-intl 설정

> npm i react-intl

이 라이브러리 이외에 딱히 설치할 것도 없다. 만약 설치나 세팅이 귀찮다면 이 글 상단에 있는 깃 저장소를 참고해도 된다. 어려운 내용은 아니니 코드를 보면 누구나 이해할 수 있다.

 폴더 구조는 react-intl만 간단하게 테스트하고 기록할 목적으로 만들어서 간단하지만, 추천 사항이 하나 있다. 꼭! locale안에 있는 번역 파일은 json으로 관리하는 것이다. export해서 사용해도 실제 사용할 수 있으나, 나중에 재밌는 도구를 사용하지 못한다(마지막쯤에 설명).

ReactDOM.render(
  <IntlProvider locale="en" messages={en}>
    <App />
  </IntlProvider>,
  document.getElementById("root")
);

 코드 구현은 IntlProvider로 우리 앱을 감싸주면 된다. 그리고 지금은 영문에 대해서만 적용하기 때문에 en.json만 만들었는데, 사용하는 언어에 따라 분리하면 관리하기 편하다. 또한 지금은 en이라고 명시해버렸지만, 실제 개발에서는 리덕스와 Selector를 이용해 언어 설정값을 가져와 사용하면 될 것이다. 

react-intl 사용

사용방법은 매우 간단하다.

// en.json
{
  "main_name": "Jacob",
}
// 번역 메시지를 사용하는 부분
<FormattedMessage id="main_name" />

이런식으로 번역 키값만 넣어주면, 번역 파일에서 locale에서 매칭 되는 값을 가져다가 보여준다.

 매우 간단하다. 이게 처음이자 끝이다. 오히려 문제라면 화면이 늘어남에 따른 번역 키값을 어떻게 효과적으로 관리할 것인지에 대한 문제이다(파이팅!). 

react-intl 활용1

처음에는 이렇게만 해도 문제없이 개발을 할 수 있었다. 근데 좀 더 다이나믹한 번역을 하고 싶은 경우가 생기기 마련이다. 예를 들어,

[사람이름], hello! Visit to this [URL]

이런 식으로 변수를 사용한 유연한 번역 메시지를 만들고 싶은 것이다. 다행히도 이 부분은 react-intl에서 지원해 준다. 이것을 만들기 위해 두 가지 파일만 수정해 보자.

// en.json
{
  "main_name": "Jacob",
  "main_greeting": "{name}, hello! Visit to this {url}."
}

번역 메시지 부분에서 변수로 사용하고 싶은 부분을 대괄호({})로 감싼다. 

 

// 번역 메시지를 사용하는 부분
      <FormattedMessage
        id="main_greeting"
        values={{
          name: "jacob",
          url: "https://code-masterjung.tistory.com/"
        }}
      />

위 코드와 같이 values라는 속성 값을 추가하고 값을 전달해 주면 된다. 알고 보면 간단하지만 이것 때문에 삽질하는 경우도 많다.

react-intl 활용 2

변수를 이용한 react-intl을 알아봤으며, 여기서 활용할 수 있는 부분은 string 뿐만 아니라 다른 것도 가능하다. 예를 들면,

      <FormattedMessage
        id="main_greeting"
        values={{
          name: "jacob",
          url: (
            <a
              href="https://code-masterjung.tistory.com/"
              target="_blank"
              rel="noopener noreferrer"
            >
              URL
            </a>
          )
        }}
      />

이런 식으로 엘리먼트를 넣어주거나, 추가한 엘리먼트에 onClick 메서드 등이 있어도 모두 사용 가능하다. 

react-intl 활용 3

마지막으로 vscode extension에 도움을 받을 수 있다. react-intl에 국한된 것은 아니지만, 알아두면 매우 쓸만한 것임을 알 수 있다.

사용 가능한 리액트 계열 패키지 - react-i18next ,  react-intl ,  next-i18next

번역 키를 직접 찾아보지 않아도 아래와 같이 사용과 동시에 표기된다.

하지만 아직 FormattedMessage에 values 속성을 줘도 i18n Ally는 작동하지 않는다. 하지만 실제로는 values 속성을 주는 일이 많지 않아 괜찮다.

locale formats

 


Intl을 적용해야하는데, 프로퍼티 타입이 string만 허용한다면?

가장 간단한 예는 react-native의 Button Component의 title 프로퍼티가 있다(물론 나중에 바뀔 수도). 

 

useIntl hook을 사용하자.

import React from 'react'
import { useIntl } from 'react-intl'

// @example
const okButton = () => {
	const { formatMessage } = useIntl();
    const title = formatMessage({ id: 'intl_key' }); // return type => string
    
    ...
    
    return(
    	...
        <Button title={title} ... />
        ...
    )
}
 

formatjs/react-intl

Internationalize React apps. This library provides React components and an API to format dates, numbers, and strings, including pluralization and handling translations. - formatjs/react-intl

github.com

https://github.com/formatjs/react-intl/blob/master/docs/API.md#useintl-hook

반응형