Definitelytyped: [@ أنواع / رد] لم يعد RefObject.current للقراءة فقط

تم إنشاؤها على ٥ ديسمبر ٢٠١٨  ·  48تعليقات  ·  مصدر: DefinitelyTyped/DefinitelyTyped

من المقبول الآن التعيين إلى ref.current ، راجع المثال: https://reactjs.org/docs/hooks-faq.html#is -there-something-like -ثيل- variables

محاولة تعيين قيمة لها يعطي الخطأ: Cannot assign to 'current' because it is a constant or a read-only property.

  • [x] حاولت استخدام الحزمة @types/react وواجهت مشاكل.
  • [x] حاولت استخدام أحدث إصدار مستقر من tsc. https://www.npmjs.com/package/typescript
  • [x] لدي سؤال غير مناسب لـ StackOverflow . (يرجى طرح أي أسئلة مناسبة هناك).
  • [x] [أذكر] (https://github.com/blog/821-mention-somebody-they-re-notified) المؤلفون (انظر Definitions by: في index.d.ts ) حتى يتمكنوا من رد.

    • المؤلفون : johnnyreillybenezech pzavolinskydigiguruericandersonmorcerftkrotoffDovydasNavickasonigoetz @ theruther4dguilhermehubnerferdaberjrakotoharisoapascalolivHotellefranklix _ _ _ _ _ _ _ _ _

التعليق الأكثر فائدة

ليست كذلك. تركت عن قصد للقراءة فقط لضمان الاستخدام الصحيح ، حتى لو لم يتم تجميدها. المراجع التي تمت تهيئتها بالقيمة null دون الإشارة تحديدًا إلى أنك تريد أن تكون قادرًا على تخصيص قيمة خالية لها يتم تفسيرها على أنها مراجع تريد أن تُدار بواسطة React - أي أن React "تمتلك" التيار وأنت تشاهده فقط.

إذا كنت تريد كائن ref قابل للتغيير يبدأ بقيمة فارغة ، فتأكد أيضًا من إعطاء | null للوسيطة العامة. هذا سيجعلها قابلة للتغيير ، لأنك "تملكها" ولا تتفاعل.

ربما يكون هذا أسهل بالنسبة لي لأن أفهمه لأنني عملت مع اللغات القائمة على المؤشر في كثير من الأحيان من قبل والملكية _ جدا_ مهمة فيها. وهذا هو المراجع ، مؤشر. يقوم .current بإلغاء الإشارة إلى المؤشر.

ال 48 كومينتر

العلاقات العامة موضع تقدير! يجب أن يكون تغيير سطر واحد سهل للغاية 😊

ferdaber ،
مرحبًا ، أحب اختيار هذه المشكلة. نظرًا لأنني جديد على الكتابة المطبوعة (أسبوع واحد فقط) وستكون هذه أول مساهمة لي في المصدر المفتوح.

لقد قمت بالاطلاع على node_modules/@types/react/index.d.ts وهناك الكود التالي في السطر رقم 61 الذي يعلن أن التيار مقروء فقط.

interface RefObject<T> {
        readonly current: T | null;
    }

إذا كانت هذه هي المشكلة ، فيمكنني حلها. هل يمكنك توجيه أول علاقات عامة خاصة بي؟
شكرا لك على وقتك :)

نعم ، إنها فقط تزيل المُعدِّل readonly هذا السطر.

يُرجع React.useRef MutableRefObject لا تكون خاصية current الخاصة به readonly . أفترض أن السؤال هو ما إذا كان يجب توحيد أنواع كائن المرجع.

يجب أن تكون موحدة ، وقت تشغيل React ليس له قيود على خاصية current التي تم إنشاؤها بواسطة React.createRef() ، الكائن نفسه مغلق ولكن غير مجمّد.

ليست كذلك. تركت عن قصد للقراءة فقط لضمان الاستخدام الصحيح ، حتى لو لم يتم تجميدها. المراجع التي تمت تهيئتها بالقيمة null دون الإشارة تحديدًا إلى أنك تريد أن تكون قادرًا على تخصيص قيمة خالية لها يتم تفسيرها على أنها مراجع تريد أن تُدار بواسطة React - أي أن React "تمتلك" التيار وأنت تشاهده فقط.

إذا كنت تريد كائن ref قابل للتغيير يبدأ بقيمة فارغة ، فتأكد أيضًا من إعطاء | null للوسيطة العامة. هذا سيجعلها قابلة للتغيير ، لأنك "تملكها" ولا تتفاعل.

ربما يكون هذا أسهل بالنسبة لي لأن أفهمه لأنني عملت مع اللغات القائمة على المؤشر في كثير من الأحيان من قبل والملكية _ جدا_ مهمة فيها. وهذا هو المراجع ، مؤشر. يقوم .current بإلغاء الإشارة إلى المؤشر.

هذا عادل ، لقد كنت أستخدم React.createRef() كدالة مساعدة لإنشاء مؤشر فقط ، لأن React لن تديره إلا إذا تم تمريره كـ ref prop ، ولكن يمكنك تمامًا مثل حسنًا ، قم بإنشاء كائن مؤشر بسيط بنفس الهيكل.

يمكننا تعديل createRef ليكون لدينا نفس منطق التحميل الزائد ، ولكن نظرًا لعدم وجود وسيطة ، يجب أن يكون مع إرجاع من النوع الشرطي. إذا قمت بتضمين | null فإنه سيعود MutableRefObject ، وإذا لم تقم بتضمينه فسيكون (غير قابل للتغيير) RefObject .

هل سيعمل ذلك مع أولئك الذين ليس لديهم strictNullTypes ممكّنًا؟

🤔

هل يجب أن نجعل من السهل كتابة رمز غير صحيح لأولئك الذين _do_ تم تمكين strictNullTypes ؟

عندما أنشأت هذه المشكلة ، لم أكن أدرك أنه كان هناك بالفعل هذا التحميل الزائد | null . إنه ليس نمطًا شائعًا جدًا لذا لم أتوقع وجود شيء من هذا القبيل. لا أعرف كيف فاتني ذلك في الوثائق رغم أنه موثق وموضح جيدًا. لا بأس بإغلاق هذا باعتباره ليس مشكلة إلا إذا كنت تريد توحيد useRef و createRef .

نظرًا لأن المشكلة نفسها كانت تستند إلى useRef وليس createRef ، فأنا موافق أيضًا على إغلاق هذا لأن قلة قليلة من الأشخاص هناك يعدلون مباشرة قيمة المؤشر التي تم إلغاء الإشارة إليها في createRef .

أتساءل عما إذا كان نمط التحميل الزائد هذا سينتج بشكل جيد ، بالنظر إلى وثائق الخطافات ، نرى عددًا قليلاً من الاستخدامات useRef مع قيمة افتراضية ، وفي هذه الحالة قد لا تكون قيمة .current أبدًا null ولكن قد يكون من المزعج نوعًا ما للمستخدمين أن يستخدموا باستمرار عامل التأكيد غير الفارغ لتجاوزه.

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

هذا نوع مما كنت أفكر فيه. Kovensky ما هي أفكارك؟

ferdaber useRef كما تم تعريفه الآن سيكون دائمًا قابلاً للتغيير _ و_ غير قابل للإلغاء ما لم تعطيه صراحةً وسيطة عامة لا تتضمن | null وقيمة أولية null .

يجب تهيئة المراجع التي تم تمريرها إلى مكون بـ null لأن هذا هو ما تشير إليه React بتعيين المراجع عند إصدارها (على سبيل المثال عند إلغاء تثبيت مكون تم تثبيته بشروط). useRef بدون تمرير قيمة سيجعلها تبدأ undefined بدلاً من ذلك ، لذلك الآن عليك أيضًا إضافة | undefined إلى شيء كان يجب أن يهتم فقط بـ | null .

المشكلة في توثيق React واستخدام useRef بدون قيمة أولية هي أن فريق React لا يبدو أنه يهتم كثيرًا بالفرق بين null و undefined . قد يكون هذا شيء تدفق.


على أي حال ، فإن الطريقة التي حددت بها useRef تتناسب تمامًا مع حالة استخدام bschlenk ، فقط أن null هي قيمة "الالتزام" ، للأسباب التي ذكرتها أعلاه.

آه ، يُظهر البحث عن كثب ذلك ، ومن المثير للاهتمام أنه تمت تهيئته كـ undefined في مصدر React بدون معلمة. رائع لذا كل شيء خوخي ، يبدو مثل 👍

أعتقد أنه أمر جيد كما هو ، من الغريب أنه سواء قمت بتضمين | null ، فإن نوع current لا يزال من الممكن أن يكون فارغًا ، فقط تغيرت قابلية التغيير. أيضًا ، دائمًا ما تمر مستندات React بشكل صريح فارغًا ، فهل من الصحيح حذف القيمة الأولية؟

إنه ليس كذلك بشكل عام ، وعلى الأقل في الماضي عندما أشرت إلى أنه في جزء من التوثيق قال فريق React أنه "حتى لو نجح" فليس المقصود أن يتم الالتزام به.

هذا هو السبب في أن الوسيطة الأولى لـ createContext مطلوبة ، على سبيل المثال ، حتى إذا كنت تريد أن يبدأ السياق بـ undefined . يجب عليك بالفعل تمرير undefined .

يبدو أنه في بعض الاستخدامات لا يستخدم المعلمة:

https://reactjs.org/docs/hooks-faq.html#is -there-something-like -ثيل-variables
https://reactjs.org/docs/hooks-faq.html#how -to-get-the-previous-props-or-state
https://reactjs.org/docs/hooks-faq.html#how -to-read-an-غالبًا-change-value-from-usecallback

ferdaber هذا لأنهم لا يهتمون بالأنواع هناك. ما هو نوع current في useRef() (بدون وسيطات)؟ undefined ؟ any ؟ مهما كان الأمر ، حتى لو أعطيت وسيطة عامة ، يجب أن تكون | ed مع undefined . _And_ إذا كان مرجعًا تستخدمه كعنصر رد فعل مرجع (ليس فقط كمخزن محلي لمؤشر الترابط) ، فيجب عليك أيضًا | null لأن React قد تكتب null هناك.

الآن تجد نفسك current هو T | null | undefined بدلاً من T فقط.

// you should always give an argument even if the docs sometimes miss them
// $ExpectError
const ref1 = useRef()
// this is a mutable ref but you can only assign `null` to it
const ref2 = useRef(null)
// this is also a mutable ref but you can only assign `undefined`
const ref3 = useRef(undefined)
// this is a mutable ref of number
const ref4 = useRef(0)
// this is a mutable ref of number | null
const ref5 = useRef<number | null>(null)
// this is a mutable ref with an object
const ref6 = useRef<React.CSSProperties>({})
// this is a mutable ref that can hold an HTMLElement
const ref7 = useRef<HTMLElement | null>(null)
// this is the only case where the ref is immutable
// you did not say in the generic argument you want to be able to write
// null into it, but you gave a null anyway.
// I am taking this as the sign that this ref is intended
// to be used as an element ref (i.e. owned by React, you're only sharing)
const ref8 = useRef<HTMLElement>(null)
// not allowed, because you didn't say you want to write undefined in it
// this is essentially what would happen if we allowed useRef with no arguments
// to make it worse, you can't use it as an element ref, because
// React might write a null into it anyway.
// $ExpectError
const ref9 = useRef<HTMLElement>(undefined)

نعم ، يعمل DX هذا بالنسبة لي ، والوثائق هي A ++ ، لذلك لا أعتقد أن معظم الناس سيشوش عليهم الأمر. شكرا لهذا التفصيل! بصراحة ، يجب فقط ربط هذه المشكلة في الكتابة :)

قد تكون هناك حالة لدعم useRef<T>() وجعلها تتصرف مثل useRef<T | undefined>(undefined) ؛ ولكن مهما كان المرجع الذي تقوم به مع ذلك لا يزال لا يمكن استخدامه كعنصر مرجع ، تمامًا مثل التخزين المحلي للخيط.

المشكلة هي ... ماذا يحدث إذا لم تقدم حجة عامة ، وهو مسموح به؟ سوف يستنتج TypeScript {} . النوع الافتراضي الصحيح هو unknown لكن لا يمكننا استخدامه.

أتلقى هذا الخطأ مع الكود التالي:

~~~ شبيبة
// ...
السماح للفاصل الزمني = useRef(باطل)؛ // حاول أيضًا باستخدام const بدلاً من let
// ...
useEffect (() => {
فاصل ثابت = setInterval (() => {/ * افعل شيئًا * /} ، 1000) ؛
interalRef.current = فاصل زمني ؛ // في هذا السطر أتلقى الخطأ

return () => {
    clearInterval(intervalRef.current);
}

})
// ...
~وعندما أقوم بإزالة readonly هنا فإنه يعمل:~ شبيبة
واجهة RefObject{
للقراءة فقط التيار: T | باطل؛
}
~~~

أنا جديد مع كل من خطافات البحث والنص المطبوع (فقط جربهما معًا) لذا قد يكون الكود الخاص بي خاطئًا

بشكل افتراضي ، إذا أنشأت مرجعًا بقيمة افتراضية null وحددت معاملته العامة ، فأنت تشير إلى نيتك في امتلاك React المرجع. إذا كنت تريد أن تكون قادرًا على تغيير المرجع الذي تملكه ، فيجب أن تعلن ذلك على النحو التالي:

const intervalRef= useRef<NodeJS.Timeout | null>(null) // <-- the generic type is NodeJS.Timeout | null

ferdaber شكرا لذلك!

أخذ هذه المرحلة إلى أبعد من ذلك والنظر إلى نوع العائد current ، فهل يجب أن يكون T بدلاً من T | null ؟ مع ظهور الخطافات ، ليس لدينا دائمًا حالة مفادها أن جميع المراجع قد تكون null ، لا سيما في الحالة المتكررة حيث يتم استدعاء useRef مع مُهيئ غير فارغ.

متابعة من قائمة الأمثلة الممتازة في https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31065#issuecomment -446660394 ، إذا كتبت:

const numericRef = useRef<number>(42);

ما هو نوع numericRef.current ؟ ليس هناك _need_ لكي يكون number | null .

إذا حددنا الأنواع والوظائف على النحو التالي:

interface RefObject<T> {
  current: T;
}

function useRef<T>(initialValue: T): RefObject<T>;
function useRef<T>(initialValue: T|null): RefObject<T | null>;

function createRef<T>(): RefObject<T | null>;

من شأنها أن تنتج الاستخدامات والأنواع التالية:

const r1 = useRef(42);
// r1 is of type RefObject<number>
// r1.current is of type number (not number | null)

const r2 = useRef<number>(null);
// r2 is of type RefObject<number | null>
// r2.current is of type number | null

const r3 = useRef(null);
// r3 is of type RefObject<null>
// r3.current is of type null

const r4 = createRef<number>();
// r4 is of type RefObject<number | null>
// r4.current is of type number | null

هل هناك شيء خاطئ؟

بالنسبة للإجابة على السؤال "ما هو نوع useRef غير المعامل؟" ، فإن الإجابة هي أن هذه المكالمة (على الرغم من الوثائق) غير صحيحة ، وفقًا لفريق React.

لقد أضفت الحمل الزائد مع | null _ على وجه التحديد _ كحمل زائد ملائم لمراجع DOM / المكوِّن ، لأنها تبدأ دائمًا فارغة ، ويتم إعادة تعيينها دائمًا إلى قيمة خالية عند إلغاء التحميل ، ولن تقوم أبدًا بإعادة تعيين التيار بنفسك ، فقط React.

للقراءة فقط هناك المزيد للحماية من الأخطاء المنطقية أكثر من تمثيل خاصية الكائن / getter-only المجمدة في JavaScript.

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

آه ، نعم ، أرى الآن أنه تمت إزالة حالة | null MutableRefObject<T> ، مقارنةً بـ RefObject<T> . لذا فإن حالة useRef<number>(42) تعمل بالفعل بشكل صحيح. شكرا على التوضيح!

ماذا علينا أن نفعل بـ createRef ؟ في الوقت الحالي ، تقوم بإرجاع RefObject<T> غير قابل للتغيير ، مما يتسبب في حدوث مشكلات في قاعدة الشفرة الخاصة بنا حيث نرغب في تمريرها واستخدامها بنفس طريقة (قابلة للتغيير) useRef ref كائنات. هل هناك طريقة يمكننا من خلالها تعديل كتابة createRef للسماح لها بتكوين كائنات ref قابلة للتغيير؟

(ويتم تعريف السمة ref على أنها من النوع Ref<T> والتي تتضمن RefObject<T> ، مما يجعل كل شيء غير قابل للتغيير. هذه مشكلة كبيرة بالنسبة لنا: حتى لو حصلنا على متغير المرجع من useRef ، لا يمكننا الاستفادة من حقيقة أنه غير قابل للتغيير من خلال مكالمة forwardRef .)

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

: null extends T ? MutableRefObject<T> : RefObject<T> يجب أن يفعل ويستخدم نفس المنطق. إذا قلت أنك تريد وضع القيم الخالية فيه ، فسيكون قابلاً للتغيير ، وإذا لم تقم بذلك فلا يزال غير قابل للتغيير بالمعنى الحالي.

هذه فكرة جميلة جدا. نظرًا لأن createRef لا يأخذ أي معلمة ، فمن المفترض أنه يحتاج دائمًا إلى تضمين خيارات | null (على عكس useRef ) ، لذلك ربما يحتاج ذلك إلى قول MutableRefObject<T | null> ؟

لم أتمكن من الحصول على أي منهما للعمل في TS. هنا ملعب TS تم تكوينه معه:
https://tinyurl.com/y75c32y3

يتم دائمًا اكتشاف النوع على أنه MutableRefObject .

في رأيك ، ما الذي يمكننا فعله بـ forwardRef ؟ يعلن أن ref هو Ref<T> ، والذي لا يتضمن إمكانية MutableRefObject .

(حالة استخدامنا التي تسبب صعوبة هي حالة الدالة mergeRefs التي تأخذ مصفوفة من المراجع ، والتي يمكن أن تكون إما مراجع وظيفية أو كائنات ref ، وتنشئ مرجعًا مجمعًا واحدًا [مرجع وظيفي] يمكن تمريره إلى أحد المكونات. يقوم هذا المرجع المجمع بتسليم أي عنصر مرجعي وارد إلى جميع المراجع المقدمة ، إما عن طريق الاتصال بهم إذا كانوا مراجع وظيفية ، أو عن طريق تعيين .current إذا كانت كائنات مرجعية. ولكن وجود RefObject<T> غير القابل للتغيير وعدم تضمين MutableRefObject<T> in Ref<T> يجعل ذلك صعبًا. هل يجب أن أطرح مشكلة منفصلة للمرجع والمرجعالصعوبات؟)

نحن لا نغير نوع useRef للأسباب المفصلة أعلاه (على الرغم من أن createRef لا يزال قيد المناقشة) ، هل لديك أي أسئلة حول الأساس المنطقي؟

هل يجب أن أطرح مشكلة منفصلة للعناصر المشمولة في https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31065#issuecomment -457650501؟

نعم ، دعنا نفصلها.

إذا كنت تريد كائن ref قابل للتغيير يبدأ بقيمة فارغة ، فتأكد أيضًا من إعطاء | null للوسيطة العامة. هذا سيجعلها قابلة للتغيير ، لأنك "تملكها" ولا تتفاعل.

شكرا على هذا! أدت إضافة قيمة خالية إلى useRef حل المشكلة بالنسبة لي.

قبل

const ref = useRef<SomeType>(null) 

// Later error: Cannot assign to 'current' because it is a constant or a read-only property.

بعد

const ref = useRef<SomeType | null>(null)

هل تم إنشاء تعليق آخر حول مكونات forwardRef؟ بشكل أساسي ، لا يمكنك إعادة توجيه المرجع وتغيير قيمته الحالية مباشرةً ، والتي أعتقد أنها جزء من نقطة إعادة توجيه المرجع.

لقد صنعت الخطاف التالي:

export const useCombinedRefs = <T>(...refs: Ref<T>[]) =>
    useCallback(
        (element: T) =>
            refs.forEach(ref => {
                if (!ref) {
                    return;
                }

                if (typeof ref === 'function') {
                    ref(element);
                } else {
                    ref.current = element; // this line produces error
                }
            }),
        refs,
    );

ويظهر لي خطأ: "لا يمكن التعيين إلى" current "لأنها خاصية للقراءة فقط."
هل هناك طريقة لحلها دون تغيير current إلى قابل للكتابة؟

لذلك ، سيتعين عليك الغش.

(ref.current as React.MutableRefObject<T> ).current = element;

نعم ، هذا غير سليم بعض الشيء ، لكن هذه هي الحالة الوحيدة التي يمكنني التفكير فيها حيث يكون هذا النوع من التخصيص متعمدًا وليس صدفة - أنت تكرر سلوكًا داخليًا لـ React وبالتالي يتعين عليك خرق القواعد.

يمكننا تعديل createRef ليكون لدينا نفس منطق التحميل الزائد ، ولكن نظرًا لعدم وجود وسيطة ، يجب أن يكون مع إرجاع من النوع الشرطي. إذا قمت بتضمين | null فإنه سيعود MutableRefObject ، وإذا لم تقم بتضمينه فسيكون (غير قابل للتغيير) RefObject .

شكر كثيرا

(ref.current as React.MutableRefObject<T>).current = element;

يجب ان يكون:

(ref as React.MutableRefObject<T>).current = element;

أنت تكرر سلوكًا داخليًا لـ React

هل هذا يعني أن المستندات هنا قديمة؟ لأنهم يصفون هذا بوضوح بأنه سير عمل مقصود ، وليس سلوكًا داخليًا.

تشير المستندات في هذه الحالة إلى المرجع الذي تملكه ، ولكن بالنسبة للمراجع التي تمررها كسمة ref لعنصر HTML ، فيجب قراءتها لك فقط.

function Component() {
  // same API, different type semantics
  const countRef = useRef<number>(0); // not readonly
  const divRef = useRef<HTMLElement>(null); // readonly

  return <button ref={divRef} onClick={() => countRef.current++}>Click me</button>
}

سيئتي ، كان ينبغي التمرير لأعلى. حصلت على خطأ حول readonly للمرجع الذي أمتلكه وافترض أن هذه هي الحالة نفسها. (أستخدم الآن سير عمل مختلفًا ولا يمكنني إعادة إنتاج الخطأ بعد الآن ، لسوء الحظ ...)

على كل حال ، شكرا جزيلا لك على الشرح!

ليس من الواضح ما إذا كان الجزء createRef من الموضوع قد تم نقله - لكنني سأقوم بالنشر هنا أيضًا.

أستخدم مكتبة تنقل شهيرة لـ React Native (React Navigation). في وثائقه ، يستدعي عادةً createRef ثم يغير المرجع. أنا متأكد من أن هذا يرجع إلى أن React لا تديرها (لا يوجد DOM).

هل يجب أن يكون نوع React Native مختلفًا؟

انظر: https://reactnavigation.org/docs/navigating-without-navigation-prop

تضمين التغريدة
لقد واجهت هذه المشكلة أيضًا عند بدء التنقل ، هل وجدت حلاً؟

تلخيص ما قرأته للتو: الطريقة الوحيدة لتعيين قيمة لمرجع تم إنشاؤه بواسطة createRef<T> هو وضعها في كل مرة تستخدمها؟ ما هو السبب وراء ذلك؟ في هذه الحالة ، فإن readonly يمنع عمليا الإعدادات من قيمة المرجع على الإطلاق ، وبالتالي يهزم الغرض الكامل من الوظيفة.

TLDR: إذا كانت القيمة الأولية الخاصة بك هي null (التفاصيل: أو شيء آخر خارج معلمة النوع) ، فقم بإضافة | null إلى معلمة النوع ، وهذا من شأنه أن يجعل .current قادرًا ليتم تعيينها مثل العادي.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات