如何在 TanStack Start v1 中格式化货币金额
显示带有货币符号和分隔符的价格
问题
价格涉及两个本地化挑战:货币表示和数字格式化。同样的货币金额在美国显示为 $1,200.50,而在德国显示为 1 200,50 €。货币符号的位置会变化,小数点和分组分隔符会互换,甚至空格的使用也会不同。
这些约定不是偏好,而是用户的期望。以不熟悉的格式显示价格会让用户质疑他们看到的金额是否正确。如果向德国用户显示“1200.50 EUR”或向美国用户显示“1.200,50$”,会造成使用障碍并削弱信任。
解决方案
根据货币和用户的语言环境格式化货币值。这将货币符号的位置与特定语言环境的数字格式规则相结合,创建符合区域期望的货币显示格式。
使用 react-intl 的 formatNumber 方法,并设置 style: 'currency' 选项,以同时应用货币代码和用户语言环境的格式化规则。浏览器的 Intl.NumberFormat API 会自动处理符号位置、分隔符选择和空格。
步骤
1. 创建一个货币格式化组件
构建一个可复用的组件,该组件接受一个数值和一个货币代码,然后根据用户的语言环境格式化价格。
import { useIntl } from "react-intl";
interface PriceProps {
value: number;
currency: string;
}
export function Price({ value, currency }: PriceProps) {
const intl = useIntl();
const formattedPrice = intl.formatNumber(value, {
style: "currency",
currency: currency,
});
return <span>{formattedPrice}</span>;
}
useIntl 钩子提供了访问格式化 API 的能力。使用 style: 'currency' 的 formatNumber 方法可以同时应用货币符号和特定语言环境的数字格式规则。
2. 使用组件处理不同的货币
通过传递数值金额和货币代码,在您的应用程序中显示价格。
export default function ProductCard() {
return (
<div>
<h2>高级计划</h2>
<Price value={1200.5} currency="USD" />
</div>
);
}
该组件会根据用户的区域设置自动格式化价格。美国用户会看到 "$1,200.50",而德国用户会看到 "1.200,50 $"。
3. 使用自定义小数精度格式化价格
通过添加 minimumFractionDigits 和 maximumFractionDigits 选项,控制显示的小数位数。
export function PriceWithPrecision({ value, currency }: PriceProps) {
const intl = useIntl();
const formattedPrice = intl.formatNumber(value, {
style: "currency",
currency: currency,
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
return <span>{formattedPrice}</span>;
}
这可以确保所有价格的小数显示一致,即使值是像 100 这样的整数。
4. 创建一个用于内联格式化的辅助工具
对于不需要组件包装的情况,可以创建一个格式化的辅助函数。
import { useIntl } from "react-intl";
export function useFormatCurrency() {
const intl = useIntl();
return (value: number, currency: string) => {
return intl.formatNumber(value, {
style: "currency",
currency: currency,
});
};
}
当您需要在属性、计算值或其他非 JSX 上下文中使用格式化价格时,可以使用此钩子。
export function CheckoutSummary({ total }: { total: number }) {
const formatCurrency = useFormatCurrency();
return (
<button aria-label={`支付 ${formatCurrency(total, "USD")}`}>结算</button>
);
}
该辅助工具返回一个适用于任何无法使用 JSX 组件的上下文的纯字符串。