كيفية تنسيق المبالغ النقدية في React Router v7
عرض الأسعار مع رموز العملات والفواصل
المشكلة
يتطلب عرض الأسعار في تطبيقات الويب التعامل مع مسألتين مترابطتين تتعلقان بالتوطين: العملة المستخدمة والاتفاقيات الإقليمية لعرض القيم النقدية. يظهر سعر 1200.50 دولار أمريكي على شكل "$1,200.50" للمستخدمين في الولايات المتحدة ولكن على شكل "1 200,50 $US" في فرنسا. يختلف موضع رمز العملة والفاصل العشري وتجميع الآلاف والمسافات حسب اللغة المحلية. عندما لا يتم احترام هذه الاتفاقيات، قد يسيء المستخدمون قراءة المبالغ أو يتساءلون عما إذا كان السعر صحيحاً، مما يقوض الثقة في التطبيق.
يزداد التحدي تعقيداً عندما يخدم التطبيق مناطق متعددة أو يسمح للمستخدمين بعرض الأسعار بعملات مختلفة. يؤدي ترميز سلاسل التنسيق بشكل ثابت أو وضع الرموز يدوياً إلى إنشاء كود هش ينكسر عند إضافة لغات محلية أو عملات جديدة. بدون نهج منهجي، يصبح الحفاظ على عرض متسق وصحيح للأسعار عبر التطبيق عرضة للأخطاء.
الحل
قم بتنسيق قيم العملة باستخدام كل من رمز العملة المستهدف واللغة المحلية النشطة للمستخدم. يفوض هذا النهج القواعد المعقدة لعرض العملة إلى واجهات برمجة التطبيقات الدولية للمتصفح، والتي تشفر بالفعل اتفاقيات التنسيق لمئات من مجموعات اللغة المحلية والعملة.
من خلال تمرير مبلغ رقمي ورمز عملة واللغة المحلية الحالية إلى دالة التنسيق، يطبق النظام تلقائياً الرمز والفواصل والتخطيط الصحيح. يضمن هذا أن تظهر الأسعار دائماً بتنسيق مألوف للمستخدم، بغض النظر عن العملة المعروضة أو المنطقة التي يتواجد فيها المستخدم.
الخطوات
1. إنشاء مكون قابل لإعادة الاستخدام لتنسيق العملة
قم ببناء مكون يستخدم FormattedNumber من react-intl مع خصائص style وcurrency لتنسيق القيم النقدية.
import { FormattedNumber } from "react-intl";
interface PriceProps {
amount: number;
currency: string;
}
export function Price({ amount, currency }: PriceProps) {
return (
<FormattedNumber value={amount} style="currency" currency={currency} />
);
}
يستخدم مكون FormattedNumber واجهة برمجة التطبيقات formatNumber ويقبل Intl.NumberFormatOptions. يخبر خيار style="currency" المنسق بتضمين رموز العملات، وتحدد خاصية currency العملة المراد عرضها.
2. استخدم مكون Price في مكونات المسار
اعرض الأسعار في أي مكون مسار React Router من خلال تمرير القيمة الرقمية ورمز العملة.
import { Price } from "~/components/Price";
export default function ProductPage() {
const product = {
name: "Wireless Headphones",
price: 129.99,
currency: "USD",
};
return (
<div>
<h1>{product.name}</h1>
<p>
<Price amount={product.price} currency={product.currency} />
</p>
</div>
);
}
ينسق مكون Price المبلغ تلقائيًا وفقًا للإعدادات المحلية المكونة في IntlProvider. بالنسبة للإعدادات المحلية الأمريكية، يعرض هذا "$129.99"؛ وبالنسبة للإعدادات المحلية الألمانية بنفس عملة الدولار الأمريكي، يعرض "129,99 $".
3. نسق العملة بشكل إجرائي عند الحاجة
للسيناريوهات التي تحتاج فيها إلى السلسلة المنسقة مباشرة، استخدم خطاف useIntl للوصول إلى طريقة formatNumber.
import { useIntl } from "react-intl";
export default function CheckoutSummary() {
const intl = useIntl();
const subtotal = 89.99;
const tax = 7.2;
const total = subtotal + tax;
const formattedTotal = intl.formatNumber(total, {
style: "currency",
currency: "EUR",
});
return (
<div>
<h2>Order Summary</h2>
<dl>
<dt>Subtotal</dt>
<dd>
{intl.formatNumber(subtotal, {
style: "currency",
currency: "EUR",
})}
</dd>
<dt>Tax</dt>
<dd>
{intl.formatNumber(tax, {
style: "currency",
currency: "EUR",
})}
</dd>
<dt>Total</dt>
<dd aria-label={`Total: ${formattedTotal}`}>
<strong>{formattedTotal}</strong>
</dd>
</dl>
</div>
);
}
تقبل طريقة formatNumber قيمة وكائن خيارات مع FormatNumberOptions. هذا مفيد عندما تحتاج إلى السلسلة المنسقة للسمات أو التسجيل أو السياقات غير JSX.
4. تحكم في دقة الكسور العشرية للعملات ذات الأرقام الصحيحة
بعض العملات لا تستخدم وحدات كسرية. اضبط عدد المنازل العشرية لتتناسب مع اصطلاحات العملة.
import { FormattedNumber } from "react-intl";
interface PriceProps {
amount: number;
currency: string;
}
export function Price({ amount, currency }: PriceProps) {
const isWholeNumberCurrency = currency === "JPY" || currency === "KRW";
return (
<FormattedNumber
value={amount}
style="currency"
currency={currency}
minimumFractionDigits={isWholeNumberCurrency ? 0 : 2}
maximumFractionDigits={isWholeNumberCurrency ? 0 : 2}
/>
);
}
الين الياباني لا يستخدم وحدة فرعية، لذلك تُعرض المبالغ بدون كسور عشرية. يتجاوز خيارا minimumFractionDigits وmaximumFractionDigits السلوك الافتراضي للكسور العشرية عند الضرورة.