Next.js(Pages Router) v16에서 통화 금액 형식 지정 방법
통화 기호 및 구분 기호와 함께 가격 표시
문제
금전적 가치를 표시하려면 통화 자체와 사용자 지역의 숫자 형식 규칙이라는 두 가지 별개의 현지화 문제를 조정해야 합니다. 1200.50의 가격은 미국 영어 사용자에게는 "$1,200.50"으로 표시되어야 하지만 독일 사용자에게는 "1 200,50 €"로 표시되어야 합니다. 통화 기호 위치, 소수점 구분 기호, 그룹 구분 기호 및 간격은 모두 로케일에 따라 다릅니다. 이러한 요소가 잘못 정렬되거나 하드코딩되면 사용자는 익숙하지 않은 형식을 보게 되어 표시된 금액이 정확한지에 대한 의구심을 갖게 되고 가격 정보에 대한 신뢰가 손상됩니다.
시각적 일관성을 넘어 잘못된 통화 형식은 실제 혼란을 야기할 수 있습니다. 쉼표를 천 단위 구분 기호로 사용하는 사용자는 "1.200"을 천이백이 아닌 일점이로 잘못 읽을 수 있습니다. 마찬가지로 잘못 배치된 통화 기호는 가격을 비전문적으로 보이게 하거나 완전히 잘못된 통화를 제안할 수 있습니다. 적절한 통화 형식은 통화 코드와 사용자의 로케일별 숫자 규칙을 모두 존중하여 가격이 즉시 명확하고 신뢰할 수 있도록 보장합니다.
솔루션
ISO 4217 통화 코드를 사용자의 활성 로케일과 결합하여 지역에 적합한 숫자 형식을 생성함으로써 통화 값의 형식을 지정합니다. 이 접근 방식은 기호 배치, 구분 기호 선택 및 간격 규칙을 국제화 라이브러리에 위임하며, 이 라이브러리는 각 로케일-통화 쌍에 대해 올바른 규칙을 적용합니다. 그 결과 애플리케이션 코드에서 수동 문자열 조작이나 로케일별 로직 없이 사용자 기대에 부합하는 가격 표시가 생성됩니다.
단계
1. 재사용 가능한 통화 형식 지정 컴포넌트 생성
숫자 값과 통화 코드를 받아들인 다음 react-intl의 컨텍스트에서 현재 로케일을 사용하여 가격 형식을 지정하는 컴포넌트를 구축합니다.
import { FormattedNumber } from "react-intl";
interface PriceProps {
value: number;
currency: string;
}
export default function Price({ value, currency }: PriceProps) {
return <FormattedNumber value={value} style="currency" currency={currency} />;
}
FormattedNumber 컴포넌트는 가장 가까운 IntlProvider에서 로케일을 읽고 통화 기호와 로케일별 숫자 형식 규칙을 자동으로 적용합니다.
2. 동적 가격 데이터가 있는 페이지에서 컴포넌트 사용하기
숫자 금액과 통화 코드를 컴포넌트에 전달하여 가격을 렌더링하면 사용자의 로케일에 맞게 형식이 자동으로 조정됩니다.
import { GetServerSideProps } from "next";
import Price from "../components/Price";
interface Product {
id: string;
name: string;
price: number;
currency: string;
}
interface ProductPageProps {
product: Product;
}
export default function ProductPage({ product }: ProductPageProps) {
return (
<div>
<h1>{product.name}</h1>
<p>
<Price value={product.price} currency={product.currency} />
</p>
</div>
);
}
export const getServerSideProps: GetServerSideProps = async () => {
const product = {
id: "1",
name: "Wireless Headphones",
price: 1299.99,
currency: "USD",
};
return {
props: {
product,
},
};
};
페이지는 통화 코드를 포함한 제품 데이터를 가져와 Price 컴포넌트에 전달하며, 이 컴포넌트는 활성 로케일에 따라 금액을 형식화합니다.
3. 명령형 통화 형식화를 위한 헬퍼 생성하기
속성 설정이나 비JSX 컨텍스트용 데이터 준비와 같이 React 컴포넌트를 사용할 수 없는 시나리오의 경우, useIntl 훅을 사용하여 형식화 함수를 노출합니다.
import { useIntl } from "react-intl";
export function useCurrencyFormatter() {
const intl = useIntl();
return (value: number, currency: string): string => {
return intl.formatNumber(value, {
style: "currency",
currency,
});
};
}
이 훅은 통화 값을 문자열로 형식화하는 함수를 반환하며, aria 레이블, 메타 태그 또는 컴포넌트가 적합하지 않은 기타 텍스트 전용 컨텍스트에 유용합니다.
4. 속성 컨텍스트에서 포매터 적용하기
명령형 포매터를 사용하여 React 엘리먼트가 아닌 일반 텍스트가 필요한 HTML 속성을 채웁니다.
import { useCurrencyFormatter } from "../hooks/useCurrencyFormatter";
interface ProductCardProps {
name: string;
price: number;
currency: string;
imageUrl: string;
}
export default function ProductCard({
name,
price,
currency,
imageUrl,
}: ProductCardProps) {
const formatCurrency = useCurrencyFormatter();
const priceLabel = formatCurrency(price, currency);
return (
<article aria-label={`${name}, ${priceLabel}`}>
<img src={imageUrl} alt={name} />
<h2>{name}</h2>
<p>{priceLabel}</p>
</article>
);
}
포매터는 aria-label 속성에 삽입할 수 있는 로컬라이즈된 통화 문자열을 생성하여, 보조 기술이 사용자의 로케일에 맞는 올바른 형식으로 가격을 알릴 수 있도록 합니다.