كيفية تنسيق الأرقام للغات المختلفة في React Router v7

عرض الأرقام بفواصل خاصة باللغة المحلية

المشكلة

تُكتب الأرقام بشكل مختلف حول العالم. ما يظهر كـ 10,000.5 في الولايات المتحدة يصبح 10.000,5 في ألمانيا—حيث تتبادل الفواصل والنقاط أدوارها تمامًا. هذه ليست مسألة تفضيل أو أسلوب، بل مسألة وضوح. قد يقرأ المستخدم الألماني 10,000.5 على أنها عشرة، متجاهلاً فواصل التجميع. وقد يقرأ المستخدم الأمريكي 10.000,5 على أنها عشرة آلاف، متجاهلاً الفاصلة العشرية.

يمكن أن تنقل نفس الأرقام معاني متعارضة اعتمادًا على الاتفاقيات الإقليمية للقارئ. عندما تعرض التطبيقات قيمًا رقمية خام دون تنسيق مراعٍ للغة المحلية، فإنها تخاطر بإرباك المستخدمين وتقويض الثقة في البيانات المعروضة.

الحل

تنسيق الأرقام بناءً على اللغة المحلية للمستخدم، باستخدام القواعد الإقليمية للفواصل العشرية وفواصل التجميع. هذا يحول القيم الرقمية إلى سلاسل نصية تتبع قواعد التنسيق المألوفة للمستخدمين في منطقتهم.

توفر مكتبة React-intl طرق تنسيق تستفيد من واجهة برمجة التطبيقات المدمجة في المتصفح Intl.NumberFormat، والتي تتعامل مع تعقيد اتفاقيات الأرقام الإقليمية. من خلال تمرير القيم الرقمية عبر هذه المنسقات، ينتج التطبيق مخرجات تتوافق مع توقعات المستخدم دون الحاجة إلى منطق فواصل يدوي.

الخطوات

1. إنشاء مكون يقوم بتنسيق الأرقام باستخدام useIntl

يوفر الخطاف useIntl إمكانية الوصول إلى طرق التنسيق بما في ذلك formatNumber، الذي يقبل قيمة رقمية ويعيد سلسلة منسقة حسب اللغة المحلية.

import { useIntl } from "react-intl";

export default function ProductPrice() {
  const intl = useIntl();
  const price = 1234.56;

  return (
    <div>
      <p>Price: {intl.formatNumber(price)}</p>
    </div>
  );
}

تطبق طريقة formatNumber تلقائيًا الفواصل الصحيحة للغة المحلية الحالية. يرى المستخدم الذي يستخدم اللغة المحلية en-US "1,234.56" بينما يرى المستخدم الذي يستخدم اللغة المحلية de-DE "1.234,56".

2. تنسيق قيم العملات باستخدام خيارات الأنماط

تقبل طريقة formatNumber خيارات متوافقة مع Intl.NumberFormatOptions، بما في ذلك تنسيق العملات.

import { useIntl } from "react-intl";

export default function ProductPrice() {
  const intl = useIntl();
  const price = 1234.56;

  return (
    <div>
      <p>
        {intl.formatNumber(price, {
          style: "currency",
          currency: "USD",
        })}
      </p>
    </div>
  );
}

هذا ينتج "$1,234.56" للغة en-US و "1.234,56 $" للغة de-DE، مع تطبيق اتفاقيات الفواصل ورموز العملات.

3. استخدام FormattedNumber للتنسيق التصريحي

يوفر مكون FormattedNumber بديلاً تصريحياً يقبل نفس الخيارات كخصائص.

import { FormattedNumber } from "react-intl";

export default function Statistics() {
  const totalUsers = 1500000;
  const growthRate = 0.23;

  return (
    <div>
      <p>
        إجمالي المستخدمين: <FormattedNumber value={totalUsers} />
      </p>
      <p>
        معدل النمو: <FormattedNumber value={growthRate} style="percent" />
      </p>
    </div>
  );
}

يقوم المكون بعرض الرقم المنسق مباشرة في DOM. بالنسبة للغة en-US، يعرض "1,500,000" و "23%". بالنسبة للغة de-DE، يعرض "1.500.000" و "23 %".

4. تنسيق الأرقام من بيانات المحمّل

في React Router 7، تصل مكونات المسار إلى بيانات المحمّل عبر خطاف useLoaderData. يمكن دمج هذا مع تنسيق الأرقام لعرض القيم المقدمة من الخادم.

import { useLoaderData } from "react-router";
import { FormattedNumber } from "react-intl";

export async function loader() {
  return {
    revenue: 45678.9,
    units: 12500,
  };
}

export default function Dashboard() {
  const { revenue, units } = useLoaderData<typeof loader>();

  return (
    <div>
      <h1>لوحة التحكم</h1>
      <p>
        الإيرادات:{" "}
        <FormattedNumber value={revenue} style="currency" currency="USD" />
      </p>
      <p>
        الوحدات المباعة: <FormattedNumber value={units} />
      </p>
    </div>
  );
}

يوفر المحمّل بيانات رقمية خام، ويقوم المكون بتنسيقها وفقاً للغة المستخدم. يحافظ هذا الفصل على استقلالية جلب البيانات عن اعتبارات العرض.