TanStack Start v1에서 다양한 로케일에 맞게 숫자 형식을 지정하는 방법
로케일별 구분 기호를 사용하여 숫자 표시하기
문제
숫자는 전 세계적으로 다르게 표기됩니다. 미국에서 10,000.5로 표시되는 것이 독일에서는 10.000,5가 됩니다—쉼표와 마침표가 완전히 역할을 바꾸는 것입니다. 이는 단순한 선호도나 스타일의 문제가 아니라 가독성의 문제입니다. 독일 사용자가 10,000.5를 보면 그룹 구분 기호를 무시하고 10으로 읽을 수 있습니다. 미국 사용자가 10.000,5를 보면 소수점 구분 기호를 무시하고 만 단위로 읽을 수 있습니다. 같은 숫자지만 정반대의 의미를 갖게 됩니다.
애플리케이션이 지역별 형식 규칙을 고려하지 않고 숫자를 표시할 때, 혼란을 초래하고 신뢰를 떨어뜨립니다. 사용자는 숫자가 자신이 배운 패턴을 따르기를 기대하며, 이러한 패턴에서 벗어나면 사용자는 멈추고, 재해석하고, 데이터가 정확한지 의문을 갖게 됩니다.
해결책
사용자의 로케일에 기반하여 숫자를 형식화하고, 소수점과 그룹 구분 기호에 지역별 규칙을 적용합니다. 이는 숫자 값을 해당 지역의 사용자에게 익숙한 형식 규칙을 따르는 문자열로 변환합니다.
React-intl은 브라우저의 내장 Intl.NumberFormat API를 활용하는 컴포넌트와 훅을 제공하여 로케일별 형식을 적용합니다. 숫자 값과 현재 로케일을 전달하면, 이러한 도구는 자동으로 올바른 구분 기호, 숫자 그룹화 및 기타 지역별 규칙을 선택합니다. 결과적으로 컴포넌트에서 수동 문자열 조작이나 로케일별 로직 없이도 사용자 기대에 맞는 형식화된 문자열을 얻을 수 있습니다.
단계
1. FormattedNumber를 사용하여 숫자 표시 컴포넌트 만들기
react-intl의 FormattedNumber 컴포넌트를 사용하여 숫자 값을 받아 로케일에 맞는 형식으로 렌더링하는 컴포넌트를 구축합니다.
import { FormattedNumber } from "react-intl";
interface PriceDisplayProps {
value: number;
}
export function PriceDisplay({ value }: PriceDisplayProps) {
return (
<div>
<FormattedNumber value={value} />
</div>
);
}
FormattedNumber 컴포넌트는 자동으로 로케일의 소수점 및 그룹 구분 기호를 적용합니다. 컴포넌트 트리에서 가장 가까운 IntlProvider에서 로케일을 읽고 그에 따라 숫자를 형식화합니다.
2. 특정 스타일로 숫자 형식 지정하기
통화, 백분율 또는 단위에 대한 스타일 옵션을 FormattedNumber에 전달하여 숫자 형식을 사용자 지정할 수 있습니다.
import { FormattedNumber } from "react-intl";
interface MetricsProps {
revenue: number;
growthRate: number;
fileSize: number;
}
export function Metrics({ revenue, growthRate, fileSize }: MetricsProps) {
return (
<div>
<p>
수익:{" "}
<FormattedNumber value={revenue} style="currency" currency="USD" />
</p>
<p>
성장률: <FormattedNumber value={growthRate} style="percent" />
</p>
<p>
크기:{" "}
<FormattedNumber
value={fileSize}
style="unit"
unit="megabyte"
unitDisplay="short"
/>
</p>
</div>
);
}
style 속성은 형식 지정 모드를 제어합니다. 통화 형식은 currency 코드가 필요하고, 백분율 형식은 자동으로 100을 곱하며, 단위 형식은 unit 식별자가 필요합니다. 모든 스타일은 활성 로케일의 규칙을 준수합니다.
3. useIntl을 사용하여 명령적으로 숫자 형식 지정하기
컴포넌트가 적합하지 않은 상황(예: 동적 속성 생성 또는 비 React API용 데이터 준비)에서 숫자 형식을 지정하려면 useIntl 훅을 사용하세요.
import { useIntl } from "react-intl";
interface ChartTooltipProps {
dataPoint: number;
}
export function ChartTooltip({ dataPoint }: ChartTooltipProps) {
const intl = useIntl();
const formattedValue = intl.formatNumber(dataPoint, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
return <div title={formattedValue}>{formattedValue}</div>;
}
formatNumber 메서드는 형식이 지정된 문자열을 즉시 반환하므로 속성, aria 레이블 또는 React 요소가 아닌 문자열로 형식이 지정된 값이 필요한 모든 상황에 적합합니다.
4. 사용자 지정 형식 옵션 적용하기
FormattedNumber 또는 formatNumber에 Intl.NumberFormatOptions를 전달하여 정밀도, 그룹화 및 표기법을 제어할 수 있습니다.
import { FormattedNumber } from "react-intl";
interface StatisticProps {
value: number;
compact?: boolean;
}
export function Statistic({ value, compact }: StatisticProps) {
return (
<div>
<FormattedNumber
value={value}
notation={compact ? "compact" : "standard"}
minimumFractionDigits={0}
maximumFractionDigits={2}
/>
</div>
);
}
notation, minimumFractionDigits, maximumFractionDigits와 같은 옵션은 숫자가 표시되는 방식을 제어합니다. 간결한 표기법은 큰 숫자를 "1.2M"과 같은 축약된 형태로 변환하면서 로케일별 약어를 준수합니다.