React: RFC: التخطيط لسمات / خصائص العنصر المخصصة في React 18

تم إنشاؤها على ٢٤ أكتوبر ٢٠١٧  ·  129تعليقات  ·  مصدر: facebook/react

هذا من المفترض أن يعالج # 7249. يوضح المستند إيجابيات وسلبيات المناهج المختلفة التي يمكن أن تستخدمها React للتعامل مع السمات والخصائص في العناصر المخصصة.

جدول المحتويات / ملخص

  • خلفية
  • اقتراحات

    • الخيار 1: قم بتعيين الخصائص فقط

    • الايجابيات



      • سهل الفهم / التنفيذ


      • يتجنب التعارض مع السمات العالمية المستقبلية


      • يستفيد من العنصر المخصص "ترقية"


      • يتم التعامل مع العناصر المخصصة مثل أي مكون React آخر



    • سلبيات



      • ربما تغيير جذري


      • تحتاج المرجع لتعيين السمة


      • غير واضح كيف سيعمل التقديم من جانب الخادم



    • الخيار 2: الخصائص إذا كانت متوفرة

    • الايجابيات



      • تغيير غير منقطع



    • سلبيات



      • يحتاج المطورون إلى فهم الكشف عن مجريات الأمور


      • قد يتعارض التراجع إلى السمات مع مستقبل الكرة الأرضية



    • الخيار 3: التفريق بين الخصائص مع سيجيل

    • الايجابيات



      • تغيير غير منقطع يمكن للمطورين الاشتراك فيه


      • على غرار كيفية تعامل المكتبات الأخرى مع السمات / الخصائص


      • النظام واضح



    • سلبيات



      • إنه بناء جملة جديد


      • غير واضح كيف سيعمل التقديم من جانب الخادم



    • الخيار 4: إضافة كائن سمات

    • الايجابيات



      • النظام واضح


      • قد يؤدي توسيع بناء الجملة أيضًا إلى حل المشكلات المتعلقة بمعالجة الأحداث



    • سلبيات



      • إنه بناء جملة جديد


      • قد يكون تغيير جذري


      • قد يكون تغيير أكبر من أي من المقترحات السابقة



    • الخيار 5: واجهة برمجة تطبيقات لاستهلاك العناصر المخصصة

    • الايجابيات



      • النظام واضح


      • تغيير غير منقطع


      • اصطلاحي للرد



    • سلبيات



      • يمكن أن يكون هناك الكثير من العمل لمكون معقد


      • قد ينتفخ حجم حزمة


      • يحتاج التكوين لمواكبة المكون



خلفية

عندما يحاول React تمرير البيانات إلى عنصر مخصص ، فإنه يفعل ذلك دائمًا باستخدام سمات HTML.

<x-foo bar={baz}> // same as setAttribute('bar', baz)

نظرًا لأنه يجب إجراء تسلسل للسمات إلى سلاسل ، فإن هذا الأسلوب يخلق مشاكل عندما تكون البيانات التي يتم تمريرها عبارة عن كائن أو صفيف. في هذا السيناريو ، ينتهي بنا الأمر بشيء مثل:

<x-foo bar="[object Object]">

الحل البديل لذلك هو استخدام ref لتعيين الخاصية يدويًا.

<x-foo ref={el => el.bar = baz}>

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

يوضح هذا المستند بعض المقترحات حول كيفية تحديث React لتحقيق ذلك.

اقتراحات

الخيار 1: قم بتعيين الخصائص فقط

بدلاً من محاولة تحديد ما إذا كان يجب تعيين خاصية أو سمة ، يمكن لـ React دائمًا تعيين خصائص على العناصر المخصصة. الرد سوف لا تحقق لمعرفة ما إذا كان يوجد الممتلكات على العنصر مسبقا.

مثال:

<x-foo bar={baz}>

ان رمز أعلاه يؤدي إلى يردون وضع .bar ملكا لل x-foo عنصر يساوي قيمة baz .

بالنسبة لأسماء الخصائص المستندة إلى camel ، يمكن أن تستخدم React نفس النمط الذي تستخدمه اليوم لخصائص مثل tabIndex .

<x-foo squidInk={pasta}> // sets .squidInk = pasta

الايجابيات

سهل الفهم / التنفيذ

هذا النموذج بسيط وواضح ومتوافق مع "واجهة برمجة تطبيقات JavaScript-centric لـ DOM" الخاصة بـ React .

أي عنصر تم إنشاؤه باستخدام مكتبات مثل Polymer أو Skate سينشئ تلقائيًا خصائص لدعم سماتها المكشوفة. يجب أن تعمل هذه العناصر جميعها مع النهج أعلاه. يتم تشجيع مطوري مكونات الفانيليا المصنّعة يدويًا على دعم السمات مع الخصائص حيث يعكس ذلك مدى الحداثة (على سبيل المثال ، ليست الكرات الفردية مثل <input> ) عناصر HTML5 ( <video> ، <audio> ، إلخ.) قد تم تنفيذ.

يتجنب التعارض مع السمات العالمية المستقبلية

عندما تعيّن React سمة على عنصر مخصص ، فهناك دائمًا خطر أن إصدارًا مستقبليًا من HTML سيشحن سمة مسماة بشكل مشابه ويكسر الأشياء. تمت مناقشة هذا القلق ref ) هذه المشكلة إلى أن تتوصل المتصفحات إلى حل أفضل.

يستفيد من العنصر المخصص "ترقية"

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

يتم التعامل مع العناصر المخصصة مثل أي مكون React آخر

عندما تمرر مكونات React البيانات إلى بعضها البعض ، فإنها تستخدم بالفعل الخصائص. سيؤدي هذا فقط إلى جعل العناصر المخصصة تتصرف بنفس الطريقة.

سلبيات

ربما تغيير جذري

إذا كان أحد المطورين يؤلف يدويًا عناصر مخصصة للفانيليا والتي لا تحتوي إلا على سمات واجهة برمجة تطبيقات ، فحينئذٍ سيحتاجون إلى تحديث كودهم وإلا فسيتعطل تطبيقهم. سيكون الإصلاح هو استخدام ref لتعيين السمة (الموضحة أدناه).

تحتاج المرجع لتعيين السمة

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

<custom-element ref={el => el.setAttribute('my-attr', val)} />

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

غير واضح كيف سيعمل التقديم من جانب الخادم

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

الخيار 2: الخصائص إذا كانت متوفرة

في وقت التشغيل ، يمكن أن يحاول React اكتشاف ما إذا كانت الخاصية موجودة في عنصر مخصص. إذا كانت الخاصية موجودة ، فستستخدمها React ، وإلا فإنها ستعود إلى تعيين سمة. هذا هو النموذج الذي يستخدمه Preact للتعامل مع العناصر المخصصة.

تنفيذ Pseudocode:

if (propName in element) {
  element[propName] = value;
} else {
  element.setAttribute(propName.toLowerCase(), value);
}

الخطوات الممكنة:

  • إذا كان للعنصر خاصية محددة ، فسيستخدمها React.

  • إذا كان لعنصر ما خاصية غير محددة ، وتحاول React تمريرها لبيانات أولية (سلسلة / رقم / منطقي) ، فستستخدم سمة.

    • بديل: تحذير ولا تحدد.
  • إذا كان لعنصر ما خاصية غير محددة ، وحاولت React تمرير كائن / مصفوفة إليه ، فستضبطه كخاصية. هذا لأن some-attr = "[كائن الكائن]" ليس مفيدًا.

    • بديل: تحذير ولا تحدد.
  • إذا تم عرض العنصر على الخادم ، وحاول React تمريره سلسلة / رقم / منطقي ، فسيستخدم سمة.

  • إذا تم عرض العنصر على الخادم ، وحاول React تمرير كائن / مصفوفة إليه ، فلن يفعل أي شيء.

الايجابيات

تغيير غير منقطع

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

سلبيات

يحتاج المطورون إلى فهم الكشف عن مجريات الأمور

قد يتم الخلط بين المطورين عندما تعيّن React سمة بدلاً من خاصية اعتمادًا على كيفية اختيارهم لتحميل عنصرهم.

قد يتعارض التراجع إلى السمات مع مستقبل الكرة الأرضية

أثار سيباستيان in للتحقق من وجود خاصية في عنصر مخصص قد يكتشف عن طريق الخطأ خاصية في الطبقة الفائقة (HTMLElement).

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

الخيار 3: التفريق بين الخصائص مع سيجيل

يمكن أن تستمر React في تعيين السمات على العناصر المخصصة ، ولكنها توفر إشارة إشارة يمكن للمطورين استخدامها لتعيين الخصائص بشكل صريح بدلاً من ذلك. هذا مشابه للنهج الذي يستخدمه Glimmer.js .

مثال بصيص:

<custom-img @src="corgi.jpg" @hiResSrc="[email protected]" width="100%">

في المثال أعلاه ، يشير @ sigil إلى أنه يجب على src و hiResSrc تمرير البيانات إلى العنصر المخصص باستخدام الخصائص ، ويجب تحويل width إلى سلسلة سمة.

نظرًا لأن مكونات React تمرر البيانات بالفعل إلى بعضها البعض باستخدام الخصائص ، فلن تكون هناك حاجة لها لاستخدام sigil (على الرغم من أنها ستنجح إذا فعلت ذلك ، إلا أنها ستكون زائدة عن الحاجة). بدلاً من ذلك ، سيتم استخدامه بشكل أساسي كتعليمات صريحة لتمرير البيانات إلى عنصر مخصص باستخدام خصائص JavaScript.

ح / ر إلى developit من Preact لاقتراح هذا النهج :)

الايجابيات

تغيير غير منقطع يمكن للمطورين الاشتراك فيه

ستستمر جميع تطبيقات العناصر المخصصة الموجودة مسبقًا في React + في العمل تمامًا كما فعلت. يمكن للمطورين اختيار ما إذا كانوا يريدون تحديث التعليمات البرمجية الخاصة بهم لاستخدام نمط sigil الجديد.

على غرار كيفية تعامل المكتبات الأخرى مع السمات / الخصائص

على غرار Glimmer ، يستخدم كل من Angular و Vue معدّلات للتمييز بين السمات والخصائص.

مثال Vue:

<!-- Vue will serialize `foo` to an attribute string, and set `squid` using a JavaScript property -->
<custom-element :foo="bar” :squid.prop=”ink”>

مثال الزاوي:

<!-- Angular will serialize `foo` to an attribute string, and set `squid` using a JavaScript property -->
<custom-element [attr.foo]="bar” [squid]=”ink”>

النظام واضح

يمكن للمطورين إخبار React بما يريدونه بالضبط بدلاً من الاعتماد على مجريات الأمور مثل نهج الخصائص إذا توفرت .

سلبيات

إنه بناء جملة جديد

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

غير واضح كيف سيعمل التقديم من جانب الخادم

هل يجب على sigil التبديل إلى استخدام سمة مسماة بشكل مشابه؟

الخيار 4: إضافة كائن سمات

يمكن أن تضيف React بناء جملة إضافيًا يسمح للمؤلفين بتمرير البيانات بشكل صريح كسمات. إذا لم يستخدم المطورون كائن السمات هذا ، فسيتم تمرير بياناتهم باستخدام خصائص JavaScript.

مثال:

const bar = 'baz';
const hello = 'World';
const width = '100%';
const ReactElement = <Test
  foo={bar} // uses JavaScript property
  attrs={{ hello, width }} // serialized to attributes
/>;

تم اقتراح هذه الفكرة في treshugart ، مؤلف Skate.js ، ويتم تنفيذها في مكتبة val .

الايجابيات

النظام واضح

يمكن للمطورين إخبار React بما يريدونه بالضبط بدلاً من الاعتماد على مجريات الأمور مثل نهج الخصائص إذا توفرت .

قد يؤدي توسيع بناء الجملة أيضًا إلى حل المشكلات المتعلقة بمعالجة الأحداث

ملاحظة: هذا خارج نطاق هذا المستند ولكن ربما يستحق الذكر :)

تطلب المشكلة رقم 7901 أن تتجاوز React نظام الأحداث التركيبية عند إضافة معالجات الأحداث التعريفية إلى العناصر المخصصة. نظرًا لأن أسماء أحداث العنصر المخصص عبارة عن سلاسل عشوائية ، فهذا يعني أنه يمكن كتابتها بأحرف كبيرة بأي طريقة. لتجاوز نظام الأحداث التركيبية اليوم ، ستعني أيضًا الحاجة إلى ابتكار دليل إرشادي لتعيين أسماء الأحداث من JSX إلى addEventListener .

// should this listen for: 'foobar', 'FooBar', or 'fooBar'?
onFooBar={handleFooBar}

ومع ذلك ، إذا تم تمديد بناء الجملة للسماح بالسمات ، فيمكن أيضًا تمديدها للسماح بالأحداث أيضًا:

const bar = 'baz';
const hello = 'World';
const SquidChanged = e => console.log('yo');
const ReactElement = <Test
  foo={bar}
  attrs={{ hello }}
  events={{ SquidChanged}} // addEventListener('SquidChanged', …)
/>;

في هذا النموذج ، يتم استخدام اسم المتغير كاسم للحدث. ليست هناك حاجة إلى إرشادية.

سلبيات

إنه بناء جملة جديد

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

قد يكون تغيير جذري

إذا كانت أي مكونات تعتمد بالفعل على الخصائص المسماة attrs أو events ، فقد يؤدي ذلك إلى كسرها.

قد يكون تغيير أكبر من أي من المقترحات السابقة

بالنسبة إلى React 17 ، قد يكون من الأسهل إجراء تغيير تدريجي (مثل أحد المقترحات السابقة) ووضع هذا الاقتراح كشيء يجب أخذه في الاعتبار من أجل إعادة بناء أكبر لاحقًا.

الخيار 5: واجهة برمجة تطبيقات لاستهلاك العناصر المخصصة

تم تقديم هذا الاقتراح بواسطة sophiebits و gaearon من فريق

يمكن لـ React إنشاء واجهة برمجة تطبيقات جديدة لاستهلاك العناصر المخصصة التي تعين سلوك العنصر مع كائن التكوين.

مثال على الكود الكاذب:

const XFoo = ReactDOM.createCustomElementType({
  element: ‘x-foo’,
  ‘my-attr’: // something that tells React what to do with it
  someRichDataProp: // something that tells React what to do with it
});

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

استخدام المثال:

<XFoo someRichDataProp={...} />

الايجابيات

النظام واضح

يمكن للمطورين إخبار React بالسلوك الذي يريدونه بالضبط.

تغيير غير منقطع

يمكن للمطورين الاشتراك في استخدام الكائن أو الاستمرار في استخدام النظام الحالي.

اصطلاحي للرد

لا يتطلب هذا التغيير بنية JSX جديدة ، ويشبه إلى حد كبير واجهات برمجة التطبيقات الأخرى في React. على سبيل المثال ، تمتلك PropTypes (على الرغم من نقلها إلى الحزمة الخاصة بها) نهجًا مشابهًا إلى حد ما.

سلبيات

يمكن أن يكون هناك الكثير من العمل لمكون معقد

يحتوي عنصر إدخال الورق في البوليمر على 37 خاصية ، لذا سينتج تكوينًا كبيرًا جدًا. إذا كان المطورون يستخدمون الكثير من العناصر المخصصة في تطبيقاتهم ، فقد يساوي ذلك الكثير من التكوينات التي يحتاجون إلى كتابتها.

قد ينتفخ حجم حزمة

فيما يتعلق بالنقطة أعلاه ، تتحمل كل فئة عنصر مخصص الآن تكلفة تعريفها + حجم عنصر التكوين الخاص بها.

ملاحظة: لست متأكدًا بنسبة 100٪ إذا كان هذا صحيحًا.

يحتاج التكوين لمواكبة المكون

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

سم مكعبsebmarkbagegaearondevelopittreshugartjustinfagnani

DOM Discussion

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

مرحبًا يا رفاق ، في هذه الأثناء بينما ننتظر ، قمت بإنشاء رقاقة لتغليف مكون الويب الخاص بك في React https://www.npmjs.com/package/reactify-wc

import React from "react";
import reactifyWc from "reactify-wc";

// Import your web component. This one defines a tag called 'vaadin-button'
import "@vaadin/vaadin-button";

const onClick = () => console.log('hello world');

const VaadinButton = reactifyWc("vaadin-button");

export const MyReactComponent = () => (
  <>
    <h1>Hello world</h1>
    <VaadinButton onClick={onClick}>
      Click me!
    </VaadinButton>
  </>
)

آمل أن يكون هذا مفيدًا

(هذا هو أول دخول لي في برمجيات المصدر المفتوح ، وواحد من أولى المصادر المفتوحة لشيء ما خارج مكتبي. النقد البناء هو أكثر من موضع ترحيب)

ال 129 كومينتر

أعتذر عن القراءة الطويلة ، لكنني أردت التأكد من أنني كنت أستكشف كل خيار بدقة. لا أريد تحيز الأشياء كثيرًا برأيي الخاص ، ولكن إذا كنت في وضع يسمح لي بالاختيار ، أعتقد أنني سأختار الخيار 3.

الخيار 3 متوافق مع الإصدارات السابقة ، وتوضيحيًا ، وصريحًا. ليست هناك حاجة للحفاظ على الكشف عن مجريات الأمور الاحتياطية ، وتوفر المكتبات الأخرى بالفعل سيجيلات / معدِّلات مماثلة.

أعتذر عن القراءة الطويلة ، لكنني أردت التأكد من أنني كنت أستكشف كل خيار بدقة. لا أريد تحيز الأشياء كثيرًا برأيي الخاص ، ولكن إذا كنت في وضع يسمح لي بالاختيار ، أعتقد أنني سأختار الخيار 3.
الخيار 3 متوافق مع الإصدارات السابقة ، وتوضيحيًا ، وصريحًا. ليست هناك حاجة للحفاظ على الكشف عن مجريات الأمور الاحتياطية ، وتوفر المكتبات الأخرى بالفعل سيجيلات / معدِّلات مماثلة.

أنا بين الخيار 2 والخيار 3 ، أعتقد أن React تعاملت مع السلوك وتغييرات API بشكل جيد جدًا في الماضي. قد يكون تقديم التحذيرات والروابط إلى المستندات مفيدًا لمساعدة المطورين على فهم ما يحدث تحت الغطاء.

يبدو الخيار 3 جذابًا بسبب طبيعته التعريفية ، أثناء قراءة كود JSX ، سيعرف المطورون القادمون الجدد على الفور ما الذي ستفعله React عند عرض العنصر.

تعليقات على الخيار 2

قد يتم الخلط بين المطورين عندما تعيّن React سمة بدلاً من خاصية اعتمادًا على كيفية اختيارهم لتحميل عنصرهم.

هل يحتاج مستهلكو العنصر المخصص إلى فهم هذا التمييز؟ أم أن هذا مهم فقط لمؤلف العنصر المخصص؟ يبدو أن مؤلف العنصر سيحتاج إلى التعامل مع السمات لأي شيء مستخدم في HTML (نظرًا لأن هذه هي الطريقة الوحيدة لتمرير البيانات من استخدام HTML) والخصائص إذا كانوا يريدون دعم القيم المعقدة أو الحصول على / تعيين خاصية من DOM. حتى أنه من الممكن أن يكون للمؤلف شيئًا ما تم تنفيذه في البداية كسمة ثم يضيف لاحقًا خاصية تحمل الاسم نفسه لدعم أنواع بيانات أكثر مرونة ولا تزال تدعم الخاصية بقيمة مخزنة في السمات.

يبدو أن تضارب التسمية مع سمات وخصائص HTMLElement المستقبلية بمثابة ضعف في معايير Web Components بشكل عام لأن ذلك يمكن أن يؤدي إلى أخطاء بغض النظر عن أسلوب الربط.

إذا كان لعنصر ما خاصية غير محددة ، وحاولت React تمرير كائن / مصفوفة إليه ، فستضبطه كخاصية. هذا لأن some-attr = "[كائن الكائن]" ليس مفيدًا.

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

تعليقات على الخيار 3

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

هل يحتاج مستهلكو العنصر المخصص إلى فهم هذا التمييز؟ أم أن هذا مهم فقط لمؤلف العنصر المخصص؟

أشك في أنها في الواقع مشكلة كبيرة لأنه ، كما أشرت ، يجب على مؤلف العنصر تحديد سمة وخاصية للقيمة الأساسية وقبول البيانات من كليهما. أود أيضًا أن أضيف أنه يجب عليهم الحفاظ على مزامنة السمة والملكية (لذا فإن تعيين أحدهما يعيّن الآخر).

يبدو أن تضارب التسمية مع سمات وخصائص HTMLElement المستقبلية بمثابة ضعف في معايير Web Components بشكل عام لأن ذلك يمكن أن يؤدي إلى أخطاء بغض النظر عن أسلوب الربط.

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

يجب أن أضيف ، بالنسبة للخصائص ، هذا ليس _ as_ سيئًا لأن الخاصية المعرفة بالعنصر ستظل الخاصية المستقبلية المضافة إلى HTMLElement. لذلك إذا كنت تمرر البيانات إلى عنصر مخصص كخاصية js ، فستستمر في العمل. يبدو أن المشكلة الرئيسية تتعلق بالسمات لأنها عالمية.

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

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

صحيح أنه إذا لم يحدد المؤلف أداة الحصول على قيمة ما ، فلن يكون هذا مفيدًا للغاية. ولكن ليس من المفيد أيضًا أن يكون لديك my-attr=[object Object] . ونظرًا لأنك لا تعرف ما إذا كانت الخاصية غير محددة حقًا أو ما إذا كان يتم تحميلها كسول ، يبدو أن تعيين الخاصية أكثر أمانًا.

من العوائق المحتملة الأخرى مع الخيار 3 أنه يتطلب من مستهلك العنصر المخصص معرفة ما إذا كان العنصر قد نفذ شيئًا ما كخاصية أو كسمة.

أعتقد أنك في الأساس في نفس المركب اليوم لأنه لا يوجد شيء يفرض على مؤلف عنصر مخصص تحديد سمة بدلاً من خاصية. لذلك يمكنني الحصول على عنصر بخصائص واجهة برمجة التطبيقات (API) فقط والتي لن تتلقى أي بيانات من نظام React الحالي وسأحتاج إلى معرفة كيفية استخدام ref لتعيين خصائص js مباشرة.

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

[تعديل]

كما ذكرت في نقطتك السابقة:

يبدو أن مؤلف العنصر سيحتاج إلى التعامل مع السمات لأي شيء مستخدم في HTML (نظرًا لأن هذه هي الطريقة الوحيدة لتمرير البيانات من استخدام HTML) والخصائص إذا كانوا يريدون دعم القيم المعقدة أو الحصول على / تعيين خاصية من DOM.

نظرًا لأنك لا تعرف أبدًا كيف سيحاول المستخدم تمرير البيانات إلى العنصر الخاص بك ، فسينتهي بك الأمر بالحاجة إلى مراسلات خاصية السمات على أي حال. أتخيل أنه إذا تم شحن الخيار 3 ، فإن معظم الأشخاص سيقومون بربط كل شيء باستخدام @ sigil لأنه سيكون أسهل. هذه هي الطريقة التي أعمل بها مع العناصر المخصصة في Vue اليوم لأنها تكشف عن مُعدِّل .prop .

يتطلب من مستهلك العنصر المخصص معرفة ما إذا كان العنصر قد نفذ شيئًا ما كخاصية أو كسمة

هذا ليس شيئًا يجب أن تقلقه React كما قال Rob في رأيي ، إنها مسؤولية مؤلف العنصر المخصص لإبلاغ المستخدم بكيفية عمل العنصر.

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

muted يعمل كسمة منطقية

render() {
  return (
    <div className="video--wrapper">
      <video muted={ this.state.muted } />
    </div>
  );
}

في الوقت الحالي ، تحتاج إلى إنشاء ref للإشارة إلى عنصر الفيديو وتغيير الخاصية.

render() {
  return (
    <div className="video--wrapper">
      <video ref={ el => this.video = el } muted={ this.state.muted } />
    </div>
  );
}

ثم قم بإنشاء معالج حدث ، طريقة مثيل وقم يدويًا بتعيين الخاصية إلى عنصر DOM.

onCurrenTimeChange(e) {
  this.video.currentTime = e.value;
}

إذا فكرت في الأمر ، فإنه يكسر نوعًا ما النموذج التصريحي الذي تفرضه React نفسها مع طبقة API و JSX المجردة منذ currentTime ، من الواضح أنها حالة في مكون المجمع ، مع ربط الخاصية ، سنظل بحاجة إلى معالج الحدث ولكن سيكون نموذج تجريد JSX أكثر وضوحًا ولن تكون المراجع ضرورية فقط لهذا:

render() {
  return (
    <div className="video--wrapper">
      <video muted={ this.state.muted } @currentTime={ this.state.currentTime } />
    </div>
  );
}

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

MustafaHosny اللهم امين :)

إذا كنا نصمم هذا من البداية ، دون الحاجة إلى التفكير في التوافق مع الإصدارات السابقة ، أعتقد أن الخيار 1 سيكون أكثر الاصطلاحات في "واجهة برمجة تطبيقات JavaScript-centric لـ DOM" الخاصة بـ React .

فيما يتعلق بالتصيير من جانب الخادم ، هل يمكن حل هذه المشكلة من خلال توفير واجهة برمجة تطبيقات لكود التطبيق لإبلاغ React بكيفية تعيين خصائص العنصر المخصص إلى السمات؟ على غرار الخرائط التي تحتفظ بها React بالفعل للسمات المحددة في النظام الأساسي؟ ستحتاج واجهة برمجة التطبيقات هذه إلى أن يتم استدعاؤها مرة واحدة فقط لكل اسم عنصر مخصص (وليس لكل مثيل منه) ، وفقط للخصائص التي لا تتبع مراسلات 1: 1 مباشرة مع سماتها ، والتي نأمل أن تكون نادرة نسبيًا.

إذا كنا قلقين من أن هذا يمثل الكثير من التغيير المفاجئ ، فأعتقد أن الخيار 3 جذاب أيضًا. إذا كان sigil يشير إلى خاصية ، فإنني أقترح "." ، نظرًا لأن هذا هو بالفعل موصّل خاصية JavaScript. ومع ذلك ، أعتقد أنه من المؤسف جعل كل مثيل يستخدم فيه عنصر مخصص في تطبيق ما مسؤولاً عن معرفة متى يجب استخدام سمة مقابل وقت استخدام خاصية ما. ما أفضله في الخيار 1 هو أنه حتى إذا كانت هناك حاجة إلى خاصية لخريطة البيانات الجدولية ، فيمكن عزل كود التعيين هذا عن جميع استخدامات JSX.

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

ربما لا أفهم عملية الترقية. عادةً ما يكون للعناصر خصائص مُعرَّفة على أنها حاصل / محددات في النموذج الأولي للفئة. التحقق من propName in element سيعيد القيمة "true" لوجود دالة getter / setter حتى لو كانت قيمة الخاصية لا تزال غير محددة. أثناء الترقية ، هل يتم تعيين قيم الخاصية على مثيل مؤقت ثم يتم نسخها لاحقًا إلى المثيل الفعلي بمجرد اكتمال التحميل البطيء؟

الترقية هي العملية التي يتلقى العنصر المخصص من خلالها فئته. قبل ذلك ، لم يكن هذا مثيلًا لتلك الفئة ، لذا فإن محصلي / محددات الملكية غير متاحين.

تضمين التغريدة

كتم يعمل كسمة منطقية

تم التحقق منه فقط وله أيضًا خاصية مقابلة على الرغم من أنه لا يبدو أنه موثق على MDN: P

في الوقت الحالي ، تحتاج إلى إنشاء مرجع يشير إلى عنصر الفيديو وتغيير الخاصية.

نعم ، ستصادف أحيانًا واجهات برمجة تطبيقات خاصة بالخصائص فقط على عناصر HTML الحديثة. currentTime بتردد عالٍ لذا لن يكون من المنطقي عكسها في سمة HTML.

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

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

robdodson yeap ، عرفت أيضًا عن الخاصية الصامتة 😄 لقد استخدمت هذين الاثنين فقط لإثبات أنه بالفعل _ في البرية_ لا توجد قاعدة مقاس واحد يناسب الجميع كما ذكرت.

سيتعين علينا الاعتماد على التوثيق على كل من العناصر الأصلية والمخصصة ، لذلك لا أمانع في اتخاذ هذا القرار.

أثناء كتابة مقتطف الشفرة الأخير ، أحببت نوعًا ما ربط الخاصية على الرغم من 💟

تضمين التغريدة

ومع ذلك ، أعتقد أنه من المؤسف جعل كل مثيل يستخدم فيه عنصر مخصص في تطبيق ما مسؤولاً عن معرفة متى يجب استخدام سمة مقابل وقت استخدام خاصية ما.

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

تضمين التغريدة

RE: الترقية. كما ذكر effulgentsia ، من الممكن أن يكون لديك عنصر مخصص على الصفحة ولكن يتم تحميل تعريفه في وقت لاحق. <x-foo> البداية نسخة من HTMLElement وعندما أقوم بتحميل تعريفه لاحقًا ، يتم "ترقيته" ويصبح مثيلًا لفئة XFoo . في هذه المرحلة ، يتم تنفيذ جميع عمليات الاسترجاعات الخاصة بدورة حياتها. نستخدم هذه التقنية في مشروع Polymer Starter Kit. نوع من مثل هذا:

<app-router>
  <my-view1></my-view1>
  <my-view2></my-view2>
</app-router>

في المثال أعلاه ، لن نقوم بتحميل تعريف my-view2 حتى يتغير جهاز التوجيه إليه.

من الممكن تمامًا تعيين خاصية على العنصر قبل ترقيته ، وبمجرد تحميل التعريف ، يمكن للعنصر الحصول على تلك البيانات أثناء إحدى عمليات رد نداء دورة حياته.

يمكن للمطورين فقط استخدام sigil لكل خاصية على عنصر مخصص

إذا بدأ المطورون في فعل ذلك ، فكيف يميز ذلك استخدام خاصية لأنك "تستطيع" من استخدام خاصية لأنك "يجب"؟ أليس هذا تمايزًا مطلوبًا للتصيير من جانب الخادم؟

إذا بدأ المطورون في فعل ذلك ، فكيف يميز ذلك استخدام خاصية لأنك "تستطيع" من استخدام خاصية لأنك "يجب"؟

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

أليس هذا تمايزًا مطلوبًا للتصيير من جانب الخادم؟

قد يكون الأمر كذلك أن sigil على الخادم قد يتراجع عن تعيين سمة.

قد يكون الأمر كذلك أن sigil على الخادم قد يتراجع عن تعيين سمة.

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

التفريق بين استخدام خاصية لأنك "تستطيع" من استخدام خاصية لأنك "يجب"

أعتقد أن هذا التمايز مهم ، لأن هناك أسبابًا مختلفة تمامًا لاختيار استخدام سمة أو خاصية كتحسين (على سبيل المثال ، تفضيل سمات SSR مقابل خصائص تفضيل العرض من جانب العميل) مقابل شيء موجود إما كسمة فقط أو فقط ملكية.

فيما يتعلق بالتصيير من جانب الخادم ، هل يمكن حل هذه المشكلة من خلال توفير واجهة برمجة تطبيقات لكود التطبيق لإبلاغ React بكيفية تعيين خصائص العنصر المخصص إلى السمات؟

لكي أكون أكثر تحديدًا ، أقترح شيئًا كهذا:

ReactDOM.defineCustomElementProp(elementName, propName, domPropertyName, htmlAttributeName, attributeSerializer)

أمثلة:

// 'muted' can be set as either a property or an attribute.
ReactDOM.defineCustomElementProp('x-foo', 'muted', 'muted', 'muted')

// 'currentTime' can only be set as a property.
ReactDOM.defineCustomElementProp('x-foo', 'currentTime', 'currentTime', null)

// 'my-attribute' can only be set as an attribute.
ReactDOM.defineCustomElementProp('x-foo', 'my-attribute', null, 'my-attribute')

// 'richData' can be set as either a property or an attribute.
// When setting as an attribute, set it as a JSON string rather than "[object Object]".
ReactDOM.defineCustomElementProp('x-foo', 'richData', 'richData', 'richdata', JSON.stringify)

بالنسبة إلى شيء لا يمكن أن يكون سوى خاصية (حيث htmlAttributeName فارغ) ، سيتخطى SSR عرضه ثم يقوم بترطيبه على العميل.

بالنسبة إلى شيء يمكن أن يكون سمة فقط (حيث يكون domPropertyName فارغًا) ، ستستدعي React setAttribute() كما هو الحال حاليًا في الإصدار 16.

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

عندما تصادف React خاصية لم يتم استدعاء defineCustomElementProp() لها ولم يتم تحديدها بواسطة مواصفات HTML كخاصية أو سمة عامة ، عندها يمكن لـ React تنفيذ بعض المنطق الافتراضي. على سبيل المثال ، ربما:

  • في الإصدار 17 ، حافظ على BC مع الإصدار 16 وقم بتعيينه كسمة.
  • في الإصدار 18 ، افترض أنه يمكن أن يكون كذلك واتبع الإستراتيجية المثلى لذلك.

ولكن على أي حال ، من خلال الاحتفاظ بواجهة برمجة تطبيقات منفصلة ، يتم الاحتفاظ بكائنات JSX و props نظيفة وداخل مساحة اسم واحدة ، تمامًا كما هو الحال بالنسبة لمكونات React وعناصر HTML غير المخصصة.

آسف للتعليقات الزائدة ، لكنني فكرت في فائدة أخرى لاقتراحي أعلاه أود مشاركتها:

يمكن توفير هذه المكالمات ReactDOM.defineCustomElementProp() في ملف JS يحتفظ به مؤلف العنصر المخصص (في نفس المستودع حيث يتم الاحتفاظ / توزيع العنصر المخصص). لن تكون هناك حاجة للعناصر المخصصة ذات المراسلات الصارمة 1: 1 للملكية / السمة ، والتي وفقًا لبيان الخلفية لهذه المشكلة هي التوصية وحالة الأغلبية على أي حال. لذلك فقط مؤلفو العناصر المخصصة الذين لا يتبعون هذه التوصية سيحتاجون إلى توفير ملف تكامل React. إذا لم يقدمه المؤلف (على سبيل المثال ، لأن مؤلف العنصر المخصص لا يهتم بـ React) ، فيمكن لمجتمع الأشخاص الذين يستخدمون هذا العنصر المخصص داخل تطبيقات React أن ينظموا ذاتيًا مستودعًا مركزيًا لإيواء ملف التكامل هذا.

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

سيكون الخيار 3 هو المفضل لدي ولكن هذا تغيير كبير ... ماذا عن العكس؟ السمات لها بادئة وليست دعائم؟

Sigils في React ، لا أعرف كيف أشعر حيال ذلك. يجب اعتبار مواصفات JSX عالمية ، ولا تعتمد بشكل مفرط أو تعتمد على تفاصيل المتصفح ، لا سيما على المخالفات بسبب التوافق مع الإصدارات السابقة. obj[prop] = value سلوك obj.setAttributes(props, value) أمر مؤسف ، لكن النظر إلى واجهة برمجة التطبيقات للمتصفحات ككل ، ليس مفاجأة. @ : [] إلى تسرب تفاصيل التنفيذ إلى السطح ويتعارض مع نهج جافا سكريبت المركزي. لذلك ، ما لم يكن لدينا مواصفات تقوم بما يلي ، أعتقد أنها فكرة سيئة: const data = <strong i="8">@myFunction</strong> // -> "[object Object]"

إذا اضطررت إلى الاعتماد على مكون ويب ، فسأكون سعيدًا إذا كانت الدلالات مخفية بعيدًا عن React و JSX بالإضافة إلى التأكد من أنها لا تقدم تغييرات متقطعة. من بين جميع الخيارات ، يبدو أن ترك ref => ... في مكانه مناسب لي. ref خصيصًا للوصول إلى الكائن. وعلى الأقل يعرف المطور بالضبط ما يحدث ، لا يوجد تسريب سيجيل ، ولا سمات جديدة يمكنها كسر المشاريع الحالية.

تضمين التغريدة

سيكون الخيار 3 هو المفضل لدي ولكن هذا تغيير كبير ... ماذا عن العكس؟ السمات لها بادئة وليست دعائم؟

لماذا سيكون تغيير جذري؟ سيظل السلوك الحالي للسمات هو الوضع الافتراضي. سيتم الاشتراك في sigil وسيستخدمه المطورون لاستبدال النقاط الموجودة في التعليمات البرمجية الخاصة بهم حيث يستخدمون حاليًا ref لتمرير البيانات إلى عنصر مخصص كخاصية JS.

تضمين التغريدة

لا سمات جديدة يمكن أن تكسر المشاريع القائمة.

هل يمكنك توضيح ما تعنيه بهذا؟

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

تضمين التغريدة

كنت أشير إلى هذا:

الخيار 4: إضافة كائن سمات
سلبيات
قد يكون تغيير جذري

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

يحتوي عنصر إدخال الورق في البوليمر على 37 خاصية ، لذا سينتج تكوينًا كبيرًا جدًا. إذا كان المطورون يستخدمون الكثير من العناصر المخصصة في تطبيقاتهم ، فقد يساوي ذلك الكثير من التكوينات التي يحتاجون إلى كتابتها.

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

import XButton from './XButton';

ويصادف أن يتم إنشاؤه بواسطة

export default ReactDOM.createCustomElementType(...)

يتيح لهم ذلك استبدال مكون React بمكوِّن مخصص يستخدم (أو حتى لا يستخدم) عناصر مخصصة في أي وقت.

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

وفي النهاية ، إذا رأينا النظام البيئي يستقر ، يمكننا اعتماد نهج أقل التكوين.

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

بناء من تعليقي السابق ، ماذا عن:

const XFoo = ReactDOM.createCustomElementType('x-foo', {
  propName1: {
    propertyName: string | null,
    attributeName: string | null,
    attributeSerializer: function | null,
    eventName: string | null,
  }
  propName2: {
  }
  ...
});

سيكون المنطق بعد ذلك ، لكل خاصية React في مثيل XFoo:

  1. إذا لم يكن eventName لهذه الخاصية خاليًا ، فقم بتسجيله كمعالج حدث يستدعي قيمة الخاصية (من المفترض أن تكون دالة).
  2. وإلا إذا لم يكن عرض جانب العميل و propertyName فارغًا ، فاضبط خاصية العنصر على قيمة prop.
  3. وإلا إذا لم يكن attributeName فارغًا ، فعيِّن سمة العنصر على قيمة الخاصية ذات السلسلة النصية. إذا لم يكن attributeSerializer فارغًا ، فاستخدمه لترتيب قيمة الخاصية. خلاف ذلك ، فقط قم بعمل '' + propValue .

يحتوي عنصر إدخال الورق في البوليمر على 37 خاصية ، لذا سينتج تكوينًا كبيرًا جدًا.

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

  • إذا كانت القيمة دالة:
eventName: the prop name,
  • آخر:
propertyName: the prop name,
attributeName: camelCaseToDashCase(the prop name),

بدلاً من ذلك ، ربما يكون من المنطقي الاحتفاظ بالأحداث في مساحة اسم منفصلة ، وفي هذه الحالة ، قم بإزالة كل ما يتعلق بـ eventName من التعليق الأخير ، وبدلاً من ذلك دع الأحداث تُسجل على النحو التالي:

<XFoo prop1={propValue1} prop2={propValue2} events={event1: functionFoo, event2: functionBar}>
</XFoo>

gaearoneffulgentsia ماذا ي 'الل التفكير في الجمع بين الخيار 1 والخيار 5؟

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

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

بالنسبة إلى SSR للخيار 1 ، يمكن دائمًا استخدام الاستدلال على سمة إذا تم عرضها على الخادم. يتم تحويل خاصية camelCase إلى سمة dash-case. يبدو أن هذا نمط شائع جدًا عبر مكتبات مكونات الويب.

تعجبني فكرة مجموعة option1 + option5 كثيرًا. بمعنى أنه بالنسبة لمعظم العناصر المخصصة:

<x-foo prop1={propValue1}>

سيعمل كما هو متوقع: يتم تعيين prop1 كخاصية من جانب العميل وكسمة من جانب الخادم.

ويمكن للأشخاص التبديل إلى الخيار 5 لأي شيء لا يناسبهم ما سبق.

سيكون تغييرًا جذريًا على الرغم من طريقة عمل React 16. بالنسبة لأي شخص يعاني من هذا الكسر (على سبيل المثال ، كانوا يستخدمون عنصرًا مخصصًا بسمات لا تدعمها الخصائص) ، يمكنهم التبديل إلى الخيار 5 ، لكنه لا يزال يمثل فاصلًا. أترك الأمر لفريق React ليقرر ما إذا كان ذلك مقبولًا.

آه ، هذا ما أحصل عليه لقراءة هذا بسرعة في القطار @ robdodson 🤦‍♂️ ... لست معجبًا بالخيار 3 الآن 🤔 لقد قرأته على أنه كل شيء في الدعائم التي يتم تهيئتها ، ومن هنا ترددي.

يبدو الخيار 5 معقولًا ومباشرًا.

أحب أين يتجهeffulgentsia . هل هناك سبب لا يمكن أن يكون:

const XFoo = ReactDOM.createCustomElementType('x-foo', {
  propName1: T.Attribute,
  propName2: T.Event,
  propName3: T.Prop
})

أو هل دعم أنواع متعددة على دعامة واحدة ذات قيمة؟

سأكون مترددًا في هذا التدفق على الرغم من effulgentsia :

إذا كانت القيمة دالة:
eventName: اسم الخاصية ،
آخر:
propertyName: اسم الخاصية ،
attributeName: camelCaseToDashCase (اسم الخاصية) ،

لا أعتقد أنني أرغب في تعيين خاصية دالة افتراضيًا لحدث ما ، وهل تعيين الخاصية propertyName و attributeName أمر منطقي؟ متى تريد دعم كلاهما لتقليد السؤال أعلاه؟ 🙂

LeeCheneler :

نقلاً عن إيجابيات الخيار 1 لملخص المشكلة:

أي عنصر تم إنشاؤه باستخدام مكتبات مثل Polymer أو Skate سينشئ تلقائيًا خصائص لدعم سماتها المكشوفة. يجب أن تعمل هذه العناصر جميعها مع النهج أعلاه. يتم تشجيع مطوري مكونات الفانيليا المصنّعة يدويًا على دعم السمات مع الخصائص حيث يعكس ذلك مدى الحداثة (على سبيل المثال ، ليست الكرات الفردية مثل <input> ) عناصر HTML5 ( <video> ، <audio> ، إلخ.) قد تم تنفيذ.

هذا هو السبب الذي يجعل تعيين كل من propertyName و attributeName أمرًا منطقيًا: لأنه يعكس الحالة الفعلية للعناصر التي تتبع أفضل الممارسات. ومن خلال جعل React مدركًا لذلك ، فإنها تسمح لـ React بتحديد أيٍّ منها يجب استخدامه بناءً على الموقف: مثل استخدام الخصائص للتصيير من جانب العميل والسمات للتصيير من جانب الخادم. بالنسبة للعناصر المخصصة التي لا تتبع أفضل الممارسات ولديها بعض السمات بدون خصائص مقابلة و / أو بعض الخصائص بدون سمات مقابلة ، يجب أن تكون React على دراية بذلك ، بحيث لا يتم عرض الخصائص التي لا تحتوي على سمات أثناء SSR و property يمكن تعيين -less-attributes مع setAttribute () أثناء التقديم من جانب العميل.

مع اقتراحك ، من المحتمل أن يتم ذلك عن طريق الجمع بين الأعلام ، مثل:

propName1: T.Property | T.Attribute,

ومع ذلك ، لن يوفر ذلك طريقة للتعبير عن اختلاف اسم السمة عن اسم الخاصية (على سبيل المثال ، camelCase إلى dash-case). كما أنه لن يوفر طريقة للتعبير عن كيفية إجراء تسلسل لكائن غني إلى سمة أثناء SSR (السلوك الحالي لـ "[كائن كائن]" ليس مفيدًا).

لا أعتقد أنني أرغب في تعيين خاصية دالة بشكل افتراضي لحدث ما

نعم ، أعتقد أنني أتفق مع ذلك أيضًا ، ومن هنا تعليق المتابعة . شكرا لإثبات صحة ترددي في ذلك!

إليك فكرة لنسخة أقل تفصيلاً من اقتراحي السابق :

const XFoo = ReactDOM.createCustomElementType('x-foo', {
  UNREFLECTED_ATTRIBUTES: [
    'my-attr-1',
    'my-attr-2',
  ],
  UNREFLECTED_PROPERTIES: [
    'myProp1',
    'myProp2',
  ],
  REFLECTED_PROPERTIES: {
    // This is default casing conversion, so could be omitted.
    someVeryLongName1: 'some-very-long-name-1',

    // In case anyone is still using all lowercase without dashes.
    someVeryLongName2: 'someverylongname2',

    // When needing to define a function for serializing a property to an attribute.
    someRichData: ['some-rich-data', JSON.stringify],
  },
});

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

من المنطقي effulgentsia 👍

يعجبني مثالك الثاني ، لكن أليس منفتحًا على الانفجار الاندماجي إذا تمت إضافة المزيد من الأنواع ، أو أحداث علاء + أي شيء قد يكون له معنى؟

- UNREFLECTED_ATTRIBUTES
- UNREFLECTED_PROPERTIES
- UNREFLECTED_EVENTS
- REFLECTED_PROPERTIES_ATTRIBUTES
- REFLECTED_PROPERTIES_EVENTS
- REFLECTED_ATTRIBUTES_EVENTS
- REFLECTED_PROPERTIES_ATTRIBUTES_EVENTS
...

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

أعتقد أن هناك فرصة هنا لكل من مجتمع React و Web Component للتوافق مع أفضل الممارسات. رد فعل الحصول على رأي هنا سيقطع شوطًا طويلاً في توجيه مؤلفي العناصر المخصصة في الاتجاه الصحيح نظرًا لاعتماده على نطاق واسع والوزن الذي تحمله آراءه.

على الرغم من أنني قمت بتأليف تنفيذ الخيار 4 ، إلا أنني مشغول دائمًا بالحاجة إلى فصل السمات والأحداث عن الخصائص. من الناحية المثالية ، أفضل الخيار 1. عمليًا ، أعتقد أنني أفضل الخيار 2 مع فتحة هروب.

يعد الخيار 1 مثاليًا ولكن هناك العديد من أنواع السمات التي لا تحتوي على خصائص مقابلة (aria / data) ، لذلك يتطلب الأمر مزيدًا من الاستدلال حول هذه الحالات وإذا كان هناك أي حالات حافة حيث قد تحتوي العناصر على سمة يجب أن يكون لها لكن لا تنفذ أحدًا لأي سبب كان. أشعر أن هذا خيار يجب النظر فيه بعناية ، ولكنه قد يكون قابلاً للتطبيق على المدى الطويل.

الخيار 2 هو الأفضل لأنه تغيير غير منقطع. سيعمل في جميع المواقف التي يتم فيها تسجيل تعريف العنصر المخصص قبل إنشاء مثيل (أو تحميله قبل تعيين الخصائص). الفن السابق لهذا الخيار هو Preact (ccdevelopit) وقد نجح حتى الآن. إن السير في هذا المسار يعطي تنفيذًا قويًا بشكل معقول وغير منكسر تم إثباته من خلال متغير React ناجح ويعمل في معظم المواقف. إذا كان هناك أي شيء ، فإنه يعطي React حلاً قصير المدى بينما يتم تقييم الحلول الأفضل على المدى الطويل.

عن الوضع (وضع الصورة؟) حيث لا عمل ذلك - تحميل المؤجلة من تعريفات عنصر العرف وأي أشخاص آخرين أننا لم يشملها - وهو فتحة الهروب على غرار ما قام به تزايدي DOM ، يمكن تنفيذها. هذا مشابه لما تقترحهeffulgentsia ، ولكن من الأفضل أن x من العناصر المخصصة. إذا أراد المستهلكون القيام بذلك على أساس كل عنصر مخصص ، فلا يزال بإمكانهم ذلك ، لأنها مجرد وظيفة. هذا يسمح لـ React بالحصول على رأي ، والتخلص من الفتحة وإرضاء جميع حالات الاستخدام من خلال تسليم المسؤولية إلى المستهلك عن جميع حالات الحافة. هذا أيضًا شيء ناقشته سابقًا مع developit حول التنفيذ في Preact. المحاذاة بين Preact / React هنا ستكون بمثابة فوز كبير.

حول الاهتمام بسمات HTML المستقبلية ، هذا شيء لا يمكننا حله ، لذلك لا أعتقد أننا يجب أن ننشغل به هنا.

يمكن توفير هذه المكالمات ReactDOM.defineCustomElementProp() في ملف JS يحتفظ به مؤلف العنصر المخصص

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

إن تحديد استدعاء مثل هذا API من قبل مستخدم عنصر مخصص مع الخصائص / السمات فقط التي يستخدمها المستخدم بالفعل هو رمز أقل للمحافظة عليه وأكثر تعبيرًا.

حتى إذا كان مؤلف المكتبة لا يستخدم React ، فإنني أجادل في أنها تجربة مستخدم أفضل لعميل مكونات الويب تلك لتعريف تكوين الخاصية مرة واحدة ثم استخدامها.

في المرة الأولى التي تستخدم فيها مكوِّن ويب يحتاج إلى خاصية ، يكون الأمر صعبًا تمامًا مثل إضافة sigil (أكثر تفصيلاً ، ولكن أيضًا أكثر وضوحًا) ولكن بعد ذلك يكون أسهل للاستخدامات اللاحقة لأنك لست بحاجة إلى التفكير فيه من أجل كل موقع اتصال من هذا المكون. في كلتا الحالتين ، تحتاج إلى فهم اختلاف الخصائص / السمات عند اعتماد مكون ويب جديد ، ولكن مع التكوين المشترك الفردي ، لا تحتاج إلى كل مستخدم لهذا المكون داخل نفس التطبيق للتفكير فيه.

من المحتمل أن نسمح بإعادة تعيين أسماء الخصائص في هذا التكوين للسماح بعمل المزيد من أسماء React-idiomatic هناك. يعد مسار الترقية إلى غلاف أكثر تعقيدًا ، إذا لزم الأمر ، أكثر سلاسة أيضًا حيث يمكنك فقط استبدال XFoo بمكون React مخصص يقوم بأي منطق ترجمة رائع يحتاجه.

بشكل أساسي: إذا كان من الممكن أن لا يفكر الأشخاص في تكوين الخاصية في كل مرة يستخدمون فيها مكونًا ، فأنا أفضل هذا النهج. لهذا السبب اقترحت الخيار 5. أعتقد أنه أكثر راحة من 3 و 4 بينما يتساوى في المرونة.

لا يعمل الخياران 1 و 2 بشكل جيد للغاية مع عرض الخادم (إنشاء HTML) ، ويؤدي الخيار 2 أيضًا إلى إنشاء مخاطر ترقية لمؤلفي مكونات الويب حيث تعد إضافة خاصية تحمل الاسم نفسه كسمة حالية الآن تغييرًا مفاجئًا. إذا قررنا أن SSR غير مفيد ، فإن الخيار 1 جذاب للغاية من منظور React. لست على دراية بما إذا كان سيكون شاملاً بما يكفي في الممارسة العملية - هل يفضح المؤلفون المكونون كل شيء عبر الخصائص؟

@ treshugart دون التعمق في حفلات الزفاف ، هل تعتقد أنه يمكنك إظهار كيف تتوقع أن تعمل "فتحة الهروب"؟ الشفرة الزائفة جيدة. فقط لذلك نحن جميعًا في نفس الصفحة.

آسف sophiebits فقط الآن رؤية ردك. أود الرد على بعض النقاط بعد قراءتها عدة مرات أخرى ولكني أردت الرد بسرعة على هذه النقطة:

لست على دراية بما إذا كان سيكون شاملاً بما يكفي في الممارسة العملية - هل يفضح المؤلفون المكونون كل شيء عبر الخصائص؟

سيعرض أي مكون تم إنشاؤه باستخدام Polymer أو Skate كل شيء عبر الخصائص. قد يكون هناك عدد قليل من القيم المتطرفة النادرة (ربما تعيين سمة فقط للتصميم أو شيء ما) ولكن بخلاف ذلك أعتقد أن الأشياء دائمًا ما تكون مدعومة بالخصائص. أنا واثق تمامًا من أن غالبية مكونات الويب قيد الإنتاج مبنية باستخدام إحدى هاتين المكتبتين.

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

لما يستحق ، لا يوجد شيء يجبرهم على استخدام السمات. تعريف العنصر المخصص هو مجرد فئة لذلك يمكن للمطور أن يفعل ما يريد. لكن من الناحية العملية ، يفضل معظم الناس استخدام تجريد مثل Polymer أو Skate لصك مكوناتها ، لذا فهم يحصلون على خصائص API مجانًا.

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

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

<x-foo long-name={val} />

ولكن ماذا عن قاعدة "do properties" إذا كان اسم الخاصية لا يحتوي على شرطات و "do attributes" إذا كان كذلك؟

robdodson : هل أنت على دراية بأي أطر عمل أو ممارسات للعناصر المخصصة هناك حيث سيكون لدى الأشخاص غلاف مختلف للسمات عن الخاصية المقابلة ، دون احتواء شرطة؟ أي ، سمة longname مع خاصية longName ؟ يبدو أن هذا هو النمط الأكثر شيوعًا مع عناصر HTML المضمنة والسمات العامة (على سبيل المثال ، contenteditable => contentEditable ) ، لكني غير واضح فيما إذا كان الآن محبطًا بدرجة كافية لسمات العناصر المخصصة بفضل البوليمر والتزلج. إذا كانت لا تزال تمثل مشكلة ، فإن JSX الموجودة مع:

<x-foo longname={val} />

قد تفشل كخاصية معينة إذا كانت الخاصية longName .

effulgentsia يمكنني التحدث فقط عن Skate ، لكننا نوصي فقط باستخدام واجهة برمجة تطبيقات السمة في حالة كتابة HTML ، والتي - لجميع المقاصد والأغراض - يمكن تصنيفها أيضًا على أنها عرض خادم. إذا كنت تفعل أي شيء عبر JS ، فيجب أن تقوم بإعداد الدعائم. تقوم واجهة برمجة تطبيقات props تلقائيًا بمزامنة / إلغاء تسلسل أحادي الاتجاه من السمات ، وتستمد اسم السمة من خلال غلاف اسم الخاصية (يصبح camelCase هو حالة الجمل ، وما إلى ذلك). هذا السلوك ككل قابل للتكوين ولكننا نشجع أفضل الممارسات على أن تكون مذكورة أعلاه.

كما ذكر الكثيرون ، تجعل الدعائم SSR صعبًا ، وهذا مصدر قلق صالح. نظرًا لأنه يبدو أن معظم الناس يفضلون الخيار 1 ، فربما نحاول المضي قدمًا في اقتراح sophiebits لوضع الدعائم على العميل مع توفير احتياطي / تعيين؟ أفترض أن هذا يعني أنه سيتم تعيين السمات على الخادم؟

على سبيل المثال ، إليك كيفية تنفيذ حالة النقل والدعائم من الخادم إلى العميل باستخدام Skate (وأي عنصر مخصص ينفذ renderedCallback() و props و / أو state واضعو. القيام بذلك على مستوى العنصر المخصص أمر تافه. إذا سار React على طريق تعيين السمات على الخادم ، فستكون معالجة الجفاف هي نفسها. لقد قدم لهم بالفعل منطق إلغاء التسلسل.

robdodson سأفعل شيئًا مشابهًا لما يفعله DOM التزايدي. سيبدو هذا مثل:

const isBrowser = true; // this would actually do the detection
const oldAttributeHook = ReactDOM.setAttribute;

// This is much like the IDOM impl but with an arguably more clear name.
ReactDOM.setAttribute = (element, name, value) => {
  // This is essentially option 2, but with the added browser check
  // to keep attr sets on the server.
  if (isBrowser && name in element) {
    element[name] = value;
  } else {
    oldAttributeHook(element, name, value);
  }
};

تضمين التغريدة

يُنشئ الخيار 2 أيضًا مخاطر الترقية لمؤلفي مكون الويب حيث تعد إضافة خاصية تحمل الاسم نفسه كسمة موجودة الآن بمثابة تغيير فاصل.

أعتقد أن هذا قد يكون لا مفر منه نظرًا لطريقة عمل السمات في النظام الأساسي. إذا استخدمت SSR عنصرًا مخصصًا ، وبالتالي يجب أن تكتب إلى سمة ، فإنك أيضًا تخاطر بأن النظام الأساسي سوف يشحن سمة تحمل نفس الاسم في المستقبل. كما ذكر treshugart من قبل ، لا أعتقد أنه شيء يمكن لـ React (أو أي مكتبة) حله. هذا شيء أرغب في تناوله مع مؤلفي مواصفات مكون الويب في TPAC لمعرفة ما إذا كان بإمكاننا إصلاحه في مساحة العنصر المخصصة.

لست متأكدًا مما إذا كان هذا يغير رأيك على الإطلاق بشأن الخيار 2 😁 ولكني أردت أن أذكر ذلك لأن الخيار 2 يحتوي على بعض المكافآت اللطيفة ويبدو أن Preact يثبت ذلك في الممارسة العملية.

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

+1 ، أنا أؤيد الاستمرار في السير في هذا الاتجاه.


تضمين التغريدة

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

الخيار 2 من شأنه أن يحل ذلك :)
وإلا ، فربما يلزم وجود دليل إرشادي مقترن بالخيار 1 الذي يعيّن سمات غلاف الشرطة إلى خصائص camelCased.

ولكن ماذا عن قاعدة "do properties" إذا كان اسم الخاصية لا يحتوي على شرطات و "do attributes" إذا كان كذلك؟

يبدو أن Preact سيعين السمة إذا كان هناك شرطة في الاسم. أفترض أن هذا بسبب استخدامهم للخيار 2 و long-name لا يجتازون الاختيار in لذلك يعود إلى سمة ( مصدر ).

أنا شخصياً أحب هذا السلوك ، لكنه يعود إلى مجال تحديد السمات والصراعات المستقبلية المحتملة ، لذا أعتقد أن sophiebits يجب أن يكون له

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

ليس هذا ما أعلمه عن. تُعد الشرطة وسيلة سهلة للمكتبة لمعرفة مكان حالة الجمل. إذا كنت تقوم بتأليف مكون ويب فانيلا يدويًا ، فيمكنك عمل longname/longName وسيوفر لك الخيار 2 فقط لأنه لن يجد خاصية longname ، لكنه سيعود إلى العنصر المستخدم سابقًا سمة longname .

لما يستحق ، يبدو أن Preact ، كملاذ أخير ، سيتصل بـ toLowerCase() على خاصية لم يتعرف عليها قبل تعيين السمة. لذلك إذا كنت تستخدم SSR'ing <x-foo longName={bar}/> ، فستتراجع أيضًا بشكل صحيح إلى السمة longname="" .


تضمين التغريدة

ربما نحاول والمضي قدمًا في اقتراح sophiebits بوضع الدعائم على العميل مع توفير احتياطي / تعيين؟ أفترض أن هذا يعني أنه سيتم تعيين السمات على الخادم؟

نعم و نعم.

سأفعل شيئًا مشابهًا لما تفعله Incremental DOM

هل الفكرة القائلة بأن كل عنصر (أو صنفه الأساسي) يحتاج إلى مزج هذا؟

راجع للشغل ، شكرًا لكم جميعًا على استمراركم في المشاركة في المناقشة ، أعلم أن الأمر قد مضى وقتًا طويلاً ❤️

لست متأكدًا من فهمي للمثال الأخير في https://github.com/facebook/react/issues/11347#issuecomment -339858314 ولكن من المستبعد جدًا أن نوفر رابطًا عالميًا يمكن تجاوزه مثل هذا.

gaearon أعتقد أن Trey كان يعرض فقط صافي التغيير على أنه رقعة قرد ، من المفترض أنه سيتم كتابته في تطبيق ReactDOM نفسه.

بناءً على التعليقات الأخيرة ، ما رأيكم جميعًا في هذا الاقتراح؟

  1. بالنسبة إلى BC ، لا تغير أي شيء حول كيفية عمل العناصر المخصصة الصغيرة في React. بعبارة أخرى ، JSX مثل <x-foo ... /> ستستمر في العمل بنفس الطريقة في React 17 كما في 16. أو ، إذا كانت إصلاحات الأخطاء _minor_ مطلوبة لذلك ، فافتح مشكلة منفصلة لمناقشة تلك الإصلاحات.

  2. أضف واجهة برمجة تطبيقات أقل تكوينًا لإنشاء مكون React مع دلالات عنصر مخصصة أفضل. على سبيل المثال ، const XFoo = ReactDOM.customElement('x-foo'); .

  3. بالنسبة للمكون الذي تم إنشاؤه أعلاه ، استخدم الدلالات التالية:

  4. لأي خاصية على XFoo تكون اسم خاصية React محجوزًا ( children ، ref ، أي أخرى؟) ، قم بتطبيق دلالات React المعتادة عليها (لا تقم بتعيينها إما كخاصية أو خاصية على عقدة DOM المخصصة للعنصر).
  5. لأي العالمية HTMLElement السمة أو الخاصية التي تحددها المواصفات HTML (بما في ذلك data-* و aria-* )، تفعل الشيء نفسه مع تلك الدعائم مثل ما رد فعل ستفعل معهم إذا كانوا على div عنصر. بعبارة أخرى ، يجب أن تكون الطريقة التي يطبق بها React الخاصيات على <XFoo data-x={} className={} contentEditable={} /> على عقدة DOM مطابقة لكيفية قيامها بذلك لـ <div data-x={} className={} contentEditable={} /> (لكلٍّ من جانب العميل و SSR).
  6. بالنسبة إلى أي خاصية على XFoo تحتوي على شرطة (بخلاف السمات العامة المسموح بها أعلاه) ، أرسل تحذيرًا (لإبلاغ المطور أن XFoo هي واجهة برمجة تطبيقات تتمحور حول الخاصية ، وليست تتمحور حول السمات ، ولا تفعل شيئًا معها (لا قم بتعيينها كخاصية أو سمة).
  7. لأي دعم في XFoo يبدأ بشرطة سفلية أو حرف ASCII علوي ، لا تفعل شيئًا به (وربما يرسل تحذيرًا؟). لا يُنصح باستخدام أيٍّ منهما لتسمية خصائص العناصر المخصصة ، لذا احتفظ بمساحات الأسماء هذه للدلالات المستقبلية (على سبيل المثال ، راجع # 4 أدناه).
  8. بالنسبة لجميع الخاصيات الأخرى على XFoo ، عند التقديم من جانب العميل ، قم بتعيينها على عقدة DOM كخاصية. بالنسبة إلى SSR ، إذا كانت القيمة بدائية ، فقم بتقديمها كسمة ؛ إذا كان غير بدائي ، تخطي التقديم وضبطه كخاصية من جانب العميل أثناء الترطيب. لعرض SSR كسمة ، حدد الاسم camelCaseToDashCase.

  9. بالنسبة للمكونات التي تم إنشاؤها عبر واجهة برمجة التطبيقات في رقم 2 أعلاه ، قم بحجز اسم خاص لاستخدامه في مستمعي الأحداث. على سبيل المثال ، 'events' أو 'eventListeners' . أو ، إذا كنت لا ترغب في التعارض مع أسماء خصائص العناصر المخصصة المحتملة ، فعندئذٍ '_eventListeners' أو 'EventListeners' . سيؤدي تطبيق ReactDom الذي أنشأه XFoo إلى تسجيل مستمعي الأحداث هؤلاء تلقائيًا على عقدة DOM.

  10. بالنسبة لحالات الحافة (على سبيل المثال ، استخدام عنصر مخصص لم يكن التنفيذ أعلاه مرغوبًا فيه أو غير كافٍ) ، يمكن لمطور التطبيق تنفيذ مكون React الخاص به للقيام بأي شيء خاص يحتاج إليه. أي أنهم لا يحتاجون إلى استخدام ReactDOM.customElement() أو يمكنهم تمديده.

  11. بالنسبة للأشخاص الذين يريدون كل السلوك أعلاه ، ولكنهم يريدون من JSX استخدام أسماء العناصر المخصصة الصغيرة ( <x-foo /> بدلاً من <XFoo /> ، لأسباب مماثلة أن الأشخاص المطلعين على كتابة HTML يفضلون <div> أكثر من <Div> ) ، يمكنهم تصحيح القرد React.createElement (). سيكون تصحيحًا بسيطًا جدًا للقرد: ما عليك سوى أخذ الوسيطة الأولى وإذا كانت تطابق اسم عنصر مخصص تريد هذا من أجله (سواء كانت هذه قائمة محددة أو أي سلسلة بها جميع الأحرف الصغيرة وشرطة واحدة على الأقل) ، ثم استدع ReactDOM.customElement() على هذا الاسم وإعادة توجيه النتيجة والوسيطات المتبقية إلى React.createElement() الأصلي.

developitgaearon أنها يمكن أن تكون إما. إذا كان "رسم الخرائط" ضروريًا ، أعتقد أن الخطاف أكثر استدامة. ومع ذلك ، كان القصد من ذلك أيضًا إظهار صافي التغيير إذا كان سيتم تنفيذه في قلب ReactDOM ، كما أشار Jason.

بالنسبة إلى BC ، لا تغير أي شيء حول كيفية عمل العناصر المخصصة الصغيرة في React. بمعنى آخر ، JSX مثل ستستمر في العمل بنفس الطريقة في React 17 كما في 16. أو ، إذا كانت هناك حاجة لإصلاحات بسيطة للأخطاء ، فافتح مشكلة منفصلة لمناقشة تلك الإصلاحات.

أنا شخصياً أفضل أن أتمكن من استخدام عنصر <x-foo> ، كما هو ، وتمرير خصائصه بسهولة دون الحاجة إلى لفه أولاً.

إذا أمكن ، أفضل استخدام اقتراح sohpiebits للخيار 1 (خصائص جانب العميل) و 5 (التكوين لـ SSR). ما زلت آمل أن يعيد الناس النظر في الخيار 2 (ربما الخيار 2 + 5؟) للحصول على مكافأة التوافق مع الإصدارات السابقة.

gaearon هل يتغير رأيك في اقتراح Trey إذا كان جزءًا من ReactDOM core؟ ربما يمكننا تجسيد المثال أكثر إذا كان ذلك سيساعد؟

اهتمامي الرئيسي بالخيار 5 هو إنشاء الكثير من النماذج المعيارية للسماح بالتشغيل البيني ، وكسر DX ، سيكون من العار على جميع فريق React الأساسي والمساهمين قضاء الكثير من الوقت في التغييرات التي لن يكون لها التأثير المطلوب.

لقد أحببت حقًا الطريقة التي تعامل بها فريق React مع التغييرات الأخيرة في الريبو ، مثل _PropTypes_ ، سيكون من الجيد التفكير في خطة تتضمن أكثر من مفتاح واحد فقط ، لتثقيف المطورين بالتغييرات المحتملة التي يجب إجراؤها في المستقبل للتخصيص وليس المخصص عناصر.

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

ربما الخيارات 5 ، مع تحذير ، الخيار 2 لاحقًا مع إهمال الغلاف المطلوب.

ربما الخيارات 5 ، مع تحذير ، الخيار 2 لاحقًا مع إهمال الغلاف المطلوب.

كنت أفكر في الواقع أن القيام بالعكس سيكون سلسلة أفضل من الخطوات. الخيار 1 أو 2 لأنه أقل تغييرًا دراماتيكيًا. وقياس كيف تسير الأمور وكيف تبدأ قصة SSR في الظهور لمكونات الويب. ثم اتبع الخيار 5 لأنه يضيف واجهة برمجة تطبيقات جديدة ومفهوم مكونات الوكيل / المجمّع.

المشكلة الرئيسية في الخيار 1 هي أنه فاصل كبير جدًا قبل الميلاد. المشكلة الرئيسية في الخيار 2 هي أنه يحتوي على حالة سباق اعتمادًا على وقت انتهاء ترقية العنصر. لست متأكدًا من أن أيًا منهما مقبول حقًا لمشروع يستخدم على نطاق واسع مثل React.

نظرًا لتوفر الخيار 5 ، أتساءل عما إذا كان بإمكاننا بدلاً من ذلك إجراء تحسينات أكثر أمانًا ، ولكن لا تزال مفيدة ، على الاستخدامات غير الاختيارية 5. على سبيل المثال ، ماذا عن عكس الخيار 4: ما عليك سوى تقديم الدعائم domProperties و eventListeners ، حتى تتمكن من القيام بأشياء مثل:

<x-foo 
  my-attr1={...} 
  domProperties={{myRichDataProperty: ...}} 
  eventListeners={{'a-custom-element-event':  e => console.log('yo')}} 
/>

هذا متوافق تمامًا مع الإصدارات السابقة ، لأنه بحكم الأحرف الكبيرة ، فإن domProperties و eventListeners ليست أسماء سمات صالحة . باستثناء ذلك ، تستدعي React 16 حاليًا setAttribute () حتى بالنسبة لأسماء الخاصية ذات الأبجدية العليا ، معتمدين على المتصفحات في كتابة الاسم بالأحرف الصغيرة داخليًا ؛ ومع ذلك ، هل يمكن أن يصدر إصدار ثانوي مستقبلي من React 16 تحذيرًا عند مواجهة عناصر مخصصة ليست أسماء سمات صالحة ، بحيث يمكن للأشخاص إصلاح أخطاء الغلاف قبل الترقية إلى React 17؟

بالإضافة إلى الحفاظ على BC ، فإن هذا النهج سهل الفهم: فهو يركز على السمة (بمعنى أن خصائص React تعامل كسمات عنصر) ، والتي تتناسب مع اعتبار أن اسم العنصر نفسه كله أحرف صغيرة وله شرطة ، وبالتالي يتمحور حول HTML. ومع ذلك ، يتم توفير domProperties للحالات النادرة نسبيًا حيث تحتاج إلى تمرير خصائص ، مثل تمرير بيانات غنية.

بالنسبة للأشخاص الذين يرغبون في تبديل نموذجهم العقلي ليكون متمحورًا حول الملكية (الخيار 1) ، هذا هو المكان الذي يمكن أن تأتي فيه واجهة برمجة تطبيقات نمط الخيار 5:

const XFoo = ReactDOM.customElement('x-foo');
<XFoo prop1={} prop2={} data-foo={} aria-label={} />

باستخدام هذه الصيغة ، يتم التعامل مع كل خاصية كخاصية (الخيار 1). وهو ما يناسب ، لأن العنصر "name" (XFoo) يتبع أيضًا اصطلاحًا مرتكزًا على JS. أعتقد أننا ما زلنا نرغب في دعم data-* و aria-* الدعائم كسمات على الأقل ، والتي يمكننا إما قصرها على تلك السمات فقط ، أو التعميم للتعامل مع أي دعامة بشرطة على أنها علامة ينسب.

في غضون ذلك ، لدعم تكوين الخيار 5 لـ SSR ، يمكننا إضافة واجهة برمجة تطبيقات التكوين إلى ReactDOM.customElement ، مثل:

const XFoo = ReactDOM.customElement('x-foo', ssrConfiguration);

ربما ssrConfiguration يمكن أن تكون وظيفة رد اتصال مماثلة لوظيفة ReactDOM.setAttribute في تعليق treshugart ؟

ماذا تعتقد؟

effulgentsia أحب أين تتجه أفكارك. طريقة إدخال الدراجات النارية قليلاً: domProps / domEvents . هذا قريب جدًا من الخيار 4.

WRT SSR ، أعتقد أنه يمكن التعامل مع SSR بواسطة العناصر المخصصة نفسها طالما أن React يمكن أن تحترم السمات التي يغيرها المكون إلى نفسه إذا لم يكن يتتبعها. لقد نشرت موجزًا ​​مسبقًا ، ولكن ها هو مرة أخرى ، للراحة: https://gist.github.com/treshugart/6eff0da3c0bea886bb56589f743b78a6. يطبق المكون السمات بشكل أساسي بعد العرض على الخادم ويعيد ترطيبها على العميل. يعد SSR لمكونات الويب أمرًا ممكنًا ، ولكن لا تزال الحلول قيد المناقشة على مستوى المعايير ، لذلك قد يكون من الأفضل انتظار هذا الجزء من الاقتراح.

effulgentsia أنا أيضًا أحب المكان الذي تتجه إليه. sophiebits ، gaearon تفعل
هل لديكم أفكار في هذا الاتجاه؟

في الثلاثاء ، 31 أكتوبر 2017 ، 7:33 مساءً كتب Trey Shugart [email protected] :

effulgentsia https://github.com/effulgentsia أحب حيث الخاص بك
الأفكار تسير. قد يكون من المفيد تحديد الأسماء قليلاً
محاذاة تسميتها: domProps / domEvents ، أو شيء من هذا القبيل.

خيار WRT 2 ، متوافق على الأقل مع الإصدارات السابقة ويحل معظم حالات الاستخدام ،
لكنني قادم إلى البدائل.

أعتقد أنه يمكن معالجة SSR بواسطة العناصر المخصصة نفسها طالما
يمكن أن تحترم React السمات التي يغيرها المكون إلى نفسه إذا كان كذلك
لا تتبعهم. لقد نشرت خلاصة في وقت سابق ، ولكن ها هي مرة أخرى ، لـ
السهولة أو الراحة:
https://gist.github.com/treshugart/6eff0da3c0bea886bb56589f743b78a6.
بشكل أساسي ، يطبق المكون السمات بعد التقديم على الخادم
وترطيبها على العميل. SSR لمكونات الويب ممكن ، ولكن
لا تزال الحلول قيد المناقشة على مستوى المعايير ، لذلك قد يكون الأمر كذلك
من الأفضل انتظار هذا الجزء من الاقتراح هنا.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/facebook/react/issues/11347#issuecomment-340960798 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe-auth/ABBFDeiQhBWNGXNplbVV1zluYxT-ntFvks5sx9hngaJpZM4QD3Zn
.

bikeshing الأسماء قليلا: domProps / domEvents.

أحب هذه الأشياء. أنا أيضًا أقوم بالعصف الذهني لمعرفة ما إذا كانت هناك طريقة لجعلها أكثر تعابيرًا اصطلاحية لـ React عن طريق استبدال مفهوم "dom" بمفهوم "ref". بمعنى آخر: refProps / refEvents ، نظرًا لأنهم يدورون حول إرفاق الدعائم ومستمعي الأحداث بـ "المرجع".

ثم فكرت ، ماذا لو بدلاً من إدخال أسماء خاصة جديدة داخل this.props ، فإننا ببساطة نفرط في تحميل السمة الحالية ref JSX. حاليًا ، "ref" هي وظيفة تُستدعى عندما يكون مكوِّن React مُركبًا وغير مُثبَّت. ماذا لو سمحنا لها أن تكون أيضًا كائنًا على النحو التالي:

<x-foo my-attr-1={}
  ref={{
    props: ...
    events: ...
    mounted: ...
    unmounted: ...
  }}
/>

مجرد فكرة.

أنا حقا أحب هذا النهج :)

ودية بينغ على هذا. gaearonsophiebits القيام ي 'الل ديك أية أفكار حول الاقتراح الأخيرeffulgentsia الصورة؟ أشعر بالفضول فقط إذا كان في الملعب أم لا.

لقد فتحنا للتو عملية RFC. هل يمكننا أن نطلب من أيٍّ منكما تقديمه باعتباره RFC؟
https://github.com/reactjs/rfcs

أفضل عدم إضافة domProperties و eventListeners "props" (أو ما يعادله داخل كائن ref = {{}}) لأنه يجعل استخدام العناصر المخصصة أمرًا غير طبيعي تمامًا وعلى عكس جميع مكونات React الأخرى. إذا كان مستخدم المكون سيحتاج إلى معرفة الفرق بين الخصائص والسمات بدقة ، وما إلى ذلك ، فأنا أفضل القيام بذلك كحل نمط ReactDOM.createCustomElementType. ثم إذا كنت تستخدم المكون بالضبط مرة واحدة فهو مقدار عمل مماثل (تحديد التكوين ثم استخدامه مرة واحدة) ، ولكن إذا كنت تستخدم المكون عدة مرات ، فلن تحتاج إلى التفكير في كائن التكوين في كل مرة. يبدو أن اشتراط تحديد التكوين في كل مرة يهزم أهداف وجود تكامل عناصر مخصصة نظيفة ما لم أفقد شيئًا ما.

sophiebits حسنًا ، يمكنني محاولة كتابة RFC لشيء من هذا القبيل. ما رأيك في الفكرة التي طرحتها في 26 أكتوبر حول الانتقال إلى العقارات أولاً من جانب العميل والسماح أيضًا للأشخاص بكتابة ReactDOM.createCustomElementType لـ SSR و / أو ما إذا كانوا يريدون حقًا تحكمًا دقيقًا في كيفية تعيين العميل للخواص / الخصائص ؟

على الأقل باستخدام النمط createCustomElementType ، يمكن للمكتبات بسهولة تعيين واجهات برمجة التطبيقات الخاصة بهم في ذلك. أي ، يمكن أن تأخذ skatejs / renderer-reaction بسهولة props وتهيئة العنصر المخصص لـ React. هذا النوع من أوراق الفانيليا عالية وجافة دون تجريد أو أداء القليل من العمل ، على الرغم من ذلك. يعجبني اقتراح روب الخاص بالتقصير الآمن ، مع السماح بالتحكم الدقيق. هل هذا شيء سيعمل؟

@ robdodson أعتقد أنني على متن الطائرة معها. لا يمكنني الوعد بأنه لن تظهر أي مخاوف أخرى ولكن أعتقد أنه يبدو وكأنه توازن جيد.

الخيار 3 هو الخيار الأفضل حتى الآن ، ويمكن أن يعمل مع SSR ، سأشرح فكرة عن كيفية القيام بذلك.

حتى الآن جميع الخيارات في حد ذاتها ، باستثناء 3 ،

  • إما أن تخلق عبئًا كبيرًا على كل شخص خارج مصدر React
  • أو يجبرون جميع مؤلفي العناصر المخصصة في الكون بأكمله على الالتزام بالقواعد الخاصة بـ React.

إليك قواعد عالمية نتفق عليها جميعًا:

  • إعداد السمات باستخدام setAttribute هو الطريقة الأكثر شيوعًا في الكون لتمرير البيانات إلى العناصر بطريقة تطابق 1 إلى 1 مع سمات HTML التصريحية. يجب أن يعمل هذا بنسبة 100٪ كقانون للكون ، وبالتالي فهو الطريقة الوحيدة المضمونة 100٪ لتمرير البيانات إلى العناصر.
  • بعض الناس ليسوا سعداء لأنه تم تصميمه من أجل الأوتار فقط.
  • بعض العناصر (أكرر ، بعض العناصر فقط ) ، تقبل القيم عبر خصائص الكائن التي _لا_ شيء يمكن الاعتماد عليه بنسبة 100٪ من الوقت.
  • يحب بعض الأشخاص خصائص الكائن لأنهم يقبلون غير سلاسل

لذلك ، على أقل تقدير ، إذا أرادت React العمل بنسبة 100٪ مع

  • يحتاج React إلى إدراك أنه ليس الله ، فهناك العديد من المكتبات الأخرى التي يستخدمها الأشخاص إلى جانب التفاعل ،
  • لذلك رد فعل shoud _ افتراضيًا_ فقط قم بتمرير البيانات عبر setAttribute لأن هذا معيار 100٪.
  • يجب أن تقبل React حقيقة أن مؤلفي Custom Element يمكنهم تمديد / تجاوز طرق setAttribute في تعريفات الفئات الخاصة بهم ، مما يجعل setAttribute يقبلون أشياء أخرى غير السلاسل. مثال رئيسي يمكن أن يكون مكتبات مثل A-frame.
  • يجب أن تقبل React أنه إذا أراد مؤلف عنصر مخصص أن يعمل عنصر مخصص مع كل مكتبة ممكنة ، _ليس فقط مع React_ ، فسيعتمد هذا المؤلف على setAttribute لجعل عنصره متوافقًا افتراضيًا مع كل شيء ، وإذا كان افتراضيًا تعتمد جميع المكتبات على السمات ، فسيعمل الكون كله مع بعضه البعض. _لا يوجد ifs أو ands أو لكن حول هذا! _ (ما لم يقم w3c / whatwg بإجراء بعض التغييرات الكبيرة)

سووووو ، هذا ما قيل ، يجب علينا على الأقل

بعد ذلك ، يمكننا التفكير في الآثار المترتبة على العناصر التي تحتوي أحيانًا على واجهة برمجة تطبيقات لخاصية الكائن:

  • للمطورين خيار استخدام setAttribute مع العلم أنه سيعمل طوال الوقت.
  • يمكن للمطورين في بعض الأحيان الاستفادة من خصائص الكائن.
  • يجب على المطورين دائمًا أن يكونوا على دراية بما إذا كانت واجهة خاصية الكائن موجودة أم لا لأي عنصر معين (مخصص أم لا).
  • تعد واجهات خاصية الكائن واجهة بديلة لا تعين بالضرورة 1 إلى 1 بالسمات.

لذلك ، مع هذه المعرفة بالسمات مقابل الخصائص ، فإن الحل في React الذي -

  1. السماح للسمات بالعمل بنسبة 100٪ من الوقت افتراضيًا. هذا يعني أن <x-foo blah="blah" /> يجب _ افتراضيًا_ تعيينه إلى setAttribute وتمرير القيمة على طول _unchanged_ . هذا تغيير لا ينكسر. في الواقع ، إنه تغيير إصلاح كان سيؤدي بخلاف ذلك إلى تمرير سلسلة "[object Object]" بلا معنى.
  2. ابتكر طريقة بديلة للسماح لمستخدم الخاصيات إذا كان المستخدم مدركًا لواجهات خصائص الكائن الموجودة ويريد استخدام تلك الواجهات بشكل صريح.

يبدو أن الخيار 3 ، باستخدام sigil (من الصعب تعلم بناء الجملة الإضافي بصراحة) ، هو الحل الأقرب إلى المثالي. بناءً على سؤال SO هذا ، فإن الرمز الوحيد المتاح هو = ، على الرغم من الاستقرار على شيء مثل & (مع نموذج قابل للإفلات ، ربما مثل \& ) هو أكثر قابلية للقراءة. على سبيل المثال ، إذا كنت أريد دعمًا محددًا:

<x-foo &blah="blah" />

يجب أن تعمل معظم الأحرف الأخرى التي تغطيها مواصفات بناء جملة WHATWG HTML ، وآمل أن تفعل ذلك ولكن هذا موضوع آخر.

الخيار 3 هو الخيار الأفضل حتى الآن.

إذا لم يتم استخدام الترطيب على العميل وبالتالي فإن الدعائم لا معنى لها في SSR ، إذن حسنًا. لم ينجح الأمر من قبل ، ولا يحتاج إلى العمل الآن. يرسل SSR بنمط PHP أو Java-style HTML ثابتًا بدون ترطيب ويعتمدان بنسبة 100٪ على السمات. وغني عن القول ، إذا استخدمنا React SSR ، فسنستخدم على الأرجح الترطيب من جانب العميل ، وإذا كنا لا نريد الترطيب ، فعلينا ببساطة أن نكون على دراية بحقيقة أنه لا ينبغي لنا استخدام الدعائم في هذه الحالة. _هذا بسيط. كل ما يجب على رد الفعل فعله هو توضيح هذا التحذير في الوثائق.

لكن!!! هذا ليس كل شئ! لا يزال بإمكاننا تضمين ميزات الخيار 5 لمنح الأشخاص مزيدًا من التحكم. مع واجهة برمجة تطبيقات مثل الخيار 5 ،

  • يمكن لبعض الأشخاص تكوين كيفية تعيين بعض السمات إلى الدعائم
  • وكيف يمكن ربط بعض الدعائم بالسمات. يمكن أن يساعد هذا الأشخاص في جعل SSR يعمل حتى مع النوع غير المرطب من SSR!
  • يمكننا السماح للأشخاص بتحديد "ما إذا كانت هذه السمة مكتوبة ، فعليًا تمريرها إلى هذه الخاصية ، ولكن إذا كانت SSR ، فلا تمررها إلى الخاصية" ، أو "تمرير هذه الخاصية إلى هذه السمة فقط أثناء SSR ، وإلا افعل ما لقد حددت استخدام علامة sigil "، وما إلى ذلك

في النهاية ، يبدو ما يلي وكأنه حل من شأنه أن ينجح:

  • الخيار 3 مع setAttribute يُستخدم افتراضيًا خلف الكواليس ،
  • مع إصلاح للرقم 10070 حتى لا تقف React في طريق الناس ،
  • وواجهة برمجة تطبيقات مثل الخيار 5 لمزيد من الضبط لأولئك الذين يحتاجون إليها حقًا ، بما في ذلك طرق ضبط SSR أو العميل أو كليهما.

سنه جديده سعيده!

أريد الرد على بعض النقاط المذكورة أعلاه ، لكني أخشى أن يكون هذا الموضوع طويلاً بالفعل. لذا ، آسف لجعله أطول: P

إليك قواعد عالمية نتفق عليها جميعًا:

تعيين السمات باستخدام setAttribute هو أكثر الطرق القياسية في الكون لتمرير البيانات إلى العناصر بطريقة تطابق 1 إلى 1 مع سمات HTML التصريحية. يجب أن يعمل هذا بنسبة 100٪ كقانون للكون ، وبالتالي فهو الطريقة الوحيدة المضمونة 100٪ لتمرير البيانات إلى العناصر.

هذا ليس صحيحًا تمامًا. لا يوجد شيء في النظام الأساسي لفرض أن العنصر المخصص يعرض واجهة السمات. يمكنك بسهولة إنشاء واحدة لا تقبل سوى خصائص JS. لذلك فهي ليست "طريقة مضمونة لتمرير البيانات". يعني الافتقار إلى آليات التنفيذ أنه لا يمكنك الاعتماد على أي من النمطين (سمات HTML أو خصائص JS) مع يقين بنسبة 100٪.

بعض الناس ليسوا سعداء لأنه تم تصميمه من أجل الأوتار فقط.
بعض العناصر (أكرر ، بعض العناصر فقط) ، تقبل القيم عبر خصائص الكائن التي ترتبط بسمات معينة. هذا ليس بالشيء الذي يمكن الاعتماد عليه بنسبة 100٪ من الوقت.

نحن نشجع الأشخاص على عدم إزعاج إنشاء سمات للخصائص التي تقبل بيانات غنية مثل الكائنات / المصفوفات. هذا لأنه لا يمكن إجراء تسلسل لبعض البيانات إلى سلسلة سمة. على سبيل المثال ، إذا كانت إحدى خصائص الكائن الخاصة بك هي إشارة إلى عقدة DOM ، فلا يمكن بالفعل تقييدها. أيضًا ، عندما تقوم بتشديد وتعديل كائن ما ، فإنه يفقد هويته. بمعنى ، إذا كان يحتوي على مرجع إلى POJO آخر ، فلا يمكنك في الواقع استخدام هذا المرجع لأنك أنشأت كائنًا جديدًا تمامًا.

يحب بعض الأشخاص خصائص الكائن لأنهم يقبلون غير سلاسل

لذلك فإن React shoud بشكل افتراضي فقط قم بتمرير البيانات عبر setAttribute لأن هذا معيار 100٪.

خصائص JavaScript قياسية. تعرض معظم عناصر HTML كلاً من السمات وواجهة الخصائص المقابلة. على سبيل المثال ، <img src=""> أو HTMLImageElement.src .

يجب أن يقبل React حقيقة أن مؤلفي Custom Element يمكنهم تمديد / تجاوز توابع setAttribute في تعريفات الفئات الخاصة بهم ، مما يجعل setAttribute يقبل أشياء أخرى غير السلاسل النصية.

يمكن للمؤلفين القيام بذلك ، ولكن هذا يبدو في الواقع أكثر "غير قياسي" من مجرد استخدام خصائص JS. قد يعرضك أيضًا لمشكلات غريبة تتعلق بتحليل واستنساخ العنصر .

يجب أن تقبل React أنه إذا أراد مؤلف عنصر مخصص أن يعمل عنصر مخصص مع كل مكتبة ممكنة ، وليس فقط مع React ، فسيعتمد هذا المؤلف على setAttribute لجعل عنصره متوافقًا افتراضيًا مع كل شيء ، وإذا كانت جميع المكتبات تعتمد افتراضيًا على السمات ، عندها سيعمل الكون كله مع بعضه البعض. لا يوجد ifs و ands أو buts حول هذا! (إلا إذا قام w3c / whatwg بإجراء بعض التغييرات الكبيرة)

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

السماح للسمات بالعمل بنسبة 100٪ من الوقت افتراضيًا. هذا يعني ذاك يجب تعيينها افتراضيًا إلى setAttribute وتمرير القيمة على طول دون تغيير. هذا تغيير لا ينكسر. في الواقع ، إنه تغيير إصلاح كان من شأنه أن يؤدي بخلاف ذلك إلى تمرير سلسلة "[كائن كائن]" بلا معنى.

أعتقد أن React _is_ تمرر القيمة دون تغيير. يؤدي استدعاء setAttribute('foo', {some: object}) إلى [object Object] . إلا إذا كنت تقترح أن يقوموا باستدعاء JSON.stringify() على الكائن؟ ولكن بعد ذلك هذا الكائن لم "يتغير". أعتقد أنك ربما تعتمد على المؤلف لتجاوز setAttribute() ؟ قد يكون من المعقول بدرجة أكبر تشجيعهم على إنشاء خصائص JS المقابلة بدلاً من ترقيع DOM.

أعتقد أن React _is_ تمرر القيمة دون تغيير. استدعاء setAttribute('foo', {some: object}) يؤدي إلى [object Object]

تقوم React بإجبار القيم على سلسلة قبل تمريرها إلى setAttribute :

https://github.com/facebook/react/blob/4d6540893809cbecb5d7490a77ec7ad32e2aeeb3/packages/react-dom/src/client/DOMPropertyOperations.js#L136

و

https://github.com/facebook/react/blob/4d6540893809cbecb5d7490a77ec7ad32e2aeeb3/packages/react-dom/src/client/DOMPropertyOperations.js#L166

أنا أتفق مع كل ما قلته.

نتفق على أن الأشخاص يقومون بالأشياء في كلا الاتجاهين ، وليس هناك معيار يجبر الجميع على القيام بذلك بطريقة أو بأخرى ، لذلك ما زلت أعتقد

  • الخيار 3 مع استخدام setAttribute افتراضيًا و sigil لتحديد استخدام خصائص المثيل ،
  • مع إصلاح لـ # 10070 بحيث لا تقوم React بإجبار السلاسل على السلاسل ،
  • والخيار 5 ، واجهة برمجة تطبيقات للضبط الدقيق

إذا تم تنفيذ الخيار 5 بشكل جيد ، فيمكن حينئذٍ لترطيب حلول SSR تعيين البيانات إلى السمات أو الدعائم كما يمكن تحديدها باستخدام الخيار 5 API.

تقوم React بفرض القيم على سلسلة قبل تمريرها إلى setAttribute

أرى. نظرًا لأن معظم الأشخاص لا يحددون toString() مخصصًا ، فإنه يتم تعيينه افتراضيًا على [object Object] .

نظرًا لأن معظم الأشخاص لا يحددون toString() مخصصًا ، فإنه يتم تعيينه افتراضيًا على [object Object] .

تمامًا كما لو فعلت

const div = document.createElement('div')
div.setAttribute('foo', {a:1, b:2, c:3})

النتيجه هي

<div foo="[object Object]"></div>

من الواضح أننا كمطورين للويب يجب أن نكون على دراية بما يحدث عندما نقوم بتمرير غير سلاسل إلى سمات العنصر. على سبيل المثال ، أنا أدرك أنه يمكنني تمرير غير السلاسل إلى عناصر A-Frame ، ويجب أن أكون حراً في القيام بذلك دون أن تعترض المكتبة الطريق.

يحتاج React إلى إدراك أنه ليس الله ، فهناك العديد من المكتبات الأخرى التي يستخدمها الأشخاص إلى جانب التفاعل

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

sebmarkbage آسف على ذلك ، لم أقصد أن أكون متغطرسًا على الإطلاق ، وأعتقد أن React هو lib جميل. كان يجب أن أفكر في كلماتي بعناية أكبر هناك (خاصةً لأن ليس كل شخص لديه نفس الدين).

ما قصدته هو أن React تحظى بشعبية كبيرة ، لذا فإن React لديها القدرة على التأثير على الأشخاص للقيام بالأشياء بطريقة معينة والتي قد لا تعمل في أماكن أخرى (على سبيل المثال ، يمكن أن تطلب من الأشخاص الاعتماد على خصائص المثيل لجميع العناصر المخصصة التي قد لا تكون " ر العمل مع جميع العناصر المخصصة).

تقوم React حاليًا بتحويل جميع القيم التي تم تمريرها إلى سمات العنصر إلى سلاسل. لو لم تفعل React هذا ، على سبيل المثال ، لن تكون هناك حاجة

إذا كان بإمكان React فقط السماح لنا بالقدرة على اتخاذ أي خيار حول كيفية تمرير البيانات إلى العناصر ، تمامًا كما هو الحال في JavaScript العادي ، فإن هذا سيجعلني أكثر المستخدمين رضاءًا. 😊

مرة أخرى ، آسف على اختياري للكلمات هناك. سأفكر مرتين في المرة القادمة.

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

أنا حريص على رؤية هذه الميزة مطبقة في React. شكرًا جزيلاً على جهودك في جعل React رائعًا.

أي تحديث على هذا RFC؟

أصبحت مكتبات Custom Element جيدة حقًا وأود استخدامها في تطبيق React الخاص بي. أي أخبار عن هذا حتى الآن؟ يعد التفاف العناصر المخصصة وترتيب محتوياتها لتحليلها مرة أخرى حلاً غير عملي إلى حد ما نظرًا لأن Vue و Angular يتعاملان مع المكونات محليًا بسهولة

أي تعديل حدث في هذه القضية؟

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

@ mgolub2 فريق

مرحبًا بالجميع ، لقد بدأت طلب سحب لإصلاح هذه المشكلة عن طريق تغيير سطرين: https://github.com/facebook/react/pull/16899

يتيح ذلك لمؤلف العنصر المخصص القيام بشيء مثل ما يلي:

class MyElement extends HTMLElement {
  setAttribute(name, value) {
    // default to existing behavior with strings
    if (typeof value === 'string')
      return super.setAttribute(name, value)

    // but now a custom element author can decide what to do with non-string values.
    if (value instanceof SomeCoolObject) { /*...*/ }
  }
}

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

فريق React ، قد تجادل بأن مؤلفي العناصر المخصصة لا ينبغي أن يفعلوا ذلك ، لأنهم يتجاوزون معالجة السمة الأصلية لـ DOM في بعض الحالات (fe عندما لا تكون القيم سلاسل). إذا كان لديك هذا الرأي ، فهذا لا يعني أنه يجب عليك إعاقة ما يمكن لمؤلفي العناصر المخصصة فعله باستخدام عناصرهم __ المخصصة __.

لا ينبغي أن تقدم React الآراء حول كيفية استخدام واجهات برمجة تطبيقات DOM الموجودة. React هي أداة للتعامل مع DOM ، ويجب عدم إبداء الرأي حول ما يمكننا فعله بـ DOM ، فقط في الطريقة التي تتدفق بها البيانات إلى DOM. بعبارة "الطريقة التي تتدفق بها البيانات إلى DOM" ، أعني المسار الذي تسلكه البيانات للوصول إلى هناك ، دون حدوث طفرة في البيانات (يؤدي تحويل كائنات المؤلف إلى سلاسل إلى تغيير بيانات المؤلف).

لماذا تريد تغيير بيانات المؤلف؟ لماذا لا تفترض فقط أن الشخص الذي يرغب في التلاعب بـ DOM يعرف ما هي البيانات التي يجب نقلها إلى DOM؟

trusktr أعتقد أن هذا تمت مناقشته في https://github.com/facebook/react/issues/10070

سأحذر الناس حقًا من إخبار مؤلفي العناصر المخصصة بتجاوز طريقة مضمنة مثل setAttribute . لا أعتقد أنه من المفترض أن نصلحها من قبل القرد. سي سي جايرون

من غير المضر تجاوز setAttribute في الفئات الفرعية من هذا القبيل (هذا ليس ترقيع القرود). ولكن كما ذكرت ، لماذا يجب أن تملي React على ذلك ، إذا لم يكن هذا بالضرورة هو عمل React lib. نريد استخدام React لمعالجة DOM (بدون عائق).

إذا اضطررت إلى استخدام el.setAttribute() يدويًا لتعزيز الأداء ، فهذا أيضًا يجعل تجربة المطورين أسوأ.

أنا لا أعتقد أن رد فعل الفريق هو إنقاذ كثير من الناس من بعض الخطر الهائل عن طريق تحويل أي شيء تمريرها إلى setAttribute إلى سلاسل.

أوافق على أن حلاً آخر قد يكون أفضل. على سبيل المثال ، تحديث مواصفات JSX للحصول على بعض البنية الجديدة ، ولكن يبدو أن ذلك يستغرق وقتًا طويلاً.

ماذا يخسر المجتمع إذا أزلنا التحويل التلقائي للسلسلة؟ ماذا يخسر فريق React؟

يمكن لفريق React تحسين الوضع لاحقًا ، مع حل أفضل ...

لماذا لا تعطينا ببساطة خيارًا لتجاوز التشديد؟ هل هذا شيء قد تكون على استعداد للنظر فيه؟

سأحذر الناس حقًا من إخبار مؤلفي العناصر المخصصة بتجاوز طريقة مضمنة مثل setAttribute .

هل يمكنك تقديم سبب وجيه للسبب؟

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

تضمين التغريدة

هل يمكنك تقديم سبب وجيه للسبب؟

مكونات الويب هي المعيار. لذلك ، يجب أن تكون مشتقات المعيار متوافقة أيضًا.

ومع ذلك ، فإن تجاوز setAttribute لا يلائم هذا الشرط: فهو ينشئ اختراقًا لـ React فقط بينما هناك الكثير من الأطر الأخرى التي تعمل مع مكونات الويب خارج الصندوق. لذلك ، سيحتاجون إلى استهلاك اختراق React حتى عندما لا يعملون مع React على الإطلاق. لا أعتقد أنه الحل الصحيح.

بعد ذلك ، من المعروف أن تصحيح الطرق القياسية هو نهج خاطئ. يؤدي تجاوز setAttribute تغيير السلوك الأصلي الذي قد يتسبب في إرباك المستخدمين النهائيين عند محاولتهم استخدامه. يتوقع الجميع أن يعمل المعيار بشكل قياسي ، والعنصر المخصص ليس استثناءً لأنه يرث سلوك HTMLElement . وعلى الرغم من أنه قد يعمل مع React ، إلا أنه يخلق فخًا لجميع المستخدمين الآخرين. على سبيل المثال ، عند استخدام مكونات الويب بدون إطار عمل ، قد يتم استدعاء setAttribute كثيرًا. أشك في أن مطوري العناصر المخصصة سيوافقون على المضي قدمًا في هذا النهج.

أنا شخصياً أعتقد أن نوعًا من غلاف React يبدو واعدًا أكثر.

مرحبًا يا رفاق ، في هذه الأثناء بينما ننتظر ، قمت بإنشاء رقاقة لتغليف مكون الويب الخاص بك في React https://www.npmjs.com/package/reactify-wc

import React from "react";
import reactifyWc from "reactify-wc";

// Import your web component. This one defines a tag called 'vaadin-button'
import "@vaadin/vaadin-button";

const onClick = () => console.log('hello world');

const VaadinButton = reactifyWc("vaadin-button");

export const MyReactComponent = () => (
  <>
    <h1>Hello world</h1>
    <VaadinButton onClick={onClick}>
      Click me!
    </VaadinButton>
  </>
)

آمل أن يكون هذا مفيدًا

(هذا هو أول دخول لي في برمجيات المصدر المفتوح ، وواحد من أولى المصادر المفتوحة لشيء ما خارج مكتبي. النقد البناء هو أكثر من موضع ترحيب)

مرحبًا يا رفاق ، في هذه الأثناء بينما ننتظر ، قمت بإنشاء رقاقة لتغليف مكون الويب الخاص بك في React https://www.npmjs.com/package/reactify-wc

import React from "react";
import reactifyWc from "reactify-wc";

// Import your web component. This one defines a tag called 'vaadin-button'
import "@vaadin/vaadin-button";

const onClick = () => console.log('hello world');

const VaadinButton = reactifyWc("vaadin-button");

export const MyReactComponent = () => (
  <>
    <h1>Hello world</h1>
    <VaadinButton onClick={onClick}>
      Click me!
    </VaadinButton>
  </>
)

آمل أن يكون هذا مفيدًا

(هذا هو أول دخول لي في برمجيات المصدر المفتوح ، وواحد من أولى المصادر المفتوحة لشيء ما خارج مكتبي. النقد البناء هو أكثر من موضع ترحيب)

المجمع العظيم :)

تجدر الإشارة أيضًا إلى أن إنشاء مكونات الويب باستخدام Stencil يعمل على إصلاح هذه المشكلة باستخدام React: https://stenciljs.com/docs/faq#can -data-be-pass-to-web-component-

matsgm يسعدني أن البناء باستخدام Stencil قد عمل من أجلك. ومع ذلك ، كإشارة تحذير ، أثبت Stencil في تجربتنا أنها لا تلعب بشكل جيد مع أطر عمل مكونات الويب الأخرى ، وتحديداً Polymer ، وقد أزعجنا نصف دزينة من المشكلات الأخرى بين أدوات البناء والدعم والوظائف العامة. قد تختلف الأميال الخاصة بك :)

مجرد محاولة للحصول على أحدث مع هذا الموضوع. ما هو الحل النهائي؟

بطريقة ما أنا من أشد المعجبين بتعريف Attr ، و prop ، و event بدلاً من الاستدلال السحري الذي يمكن أن يكون مربكًا للغاية.

على سبيل المثال ، يستخدم snabbdom تباعد أسماء على مستوى عالٍ صريح ، مما يجعل من السهل معرفة أين يذهب. لا يوجد أي تلاعب بالسلسلة وهو أسرع في التنفيذ ، على سبيل المثال لا يزال اقتطاع اللاحقة من onClick => click نجاحًا مثاليًا.

<input attrs={{placeholder: `heyo`}} style={{color: `inherit`}} class={{hello: true, world: false}} on={{click: this.handleClick}} props={{value: `blah`}} />
attr = (attr, val) => elem.setAttribute(attr, val);
prop = (prop, val) => elem[prop] = val;
on  = (event, handler) => elem.addEventListener(event, handler)
style = (prop, val) => elem.style[prop] = val;
class = (name, isSet) => isSet ? elem.classList.add(name) : elem.classList.remove(val)
dataset = (key, val) => elem.dataset[key] = val;

أتمنى أن تدعم JSX مساحة الاسم مع بناء الجملة. هذا يعني أن الخاصيات ستكون مساحة اسم افتراضية ويمكننا ببساطة الكتابة

<div tabIndex={-1} attr.title={"abcd"} on.click={handler} style.opacity={1} class.world={true} />`

fyisebmarkbage ^

const whatever = 'Whatever';
const obj = { a: 1, b: 2 };
const reactComponent = (props) => (
<div>
  ...
  <custom-element attr="{whatever}" someProp={obj} />
  { /* double quotes for attributes */ }
  { /* no quotes for properties */ }
</div>
);

يمكن تحقيق ذلك عن طريق تعديل محلل React JSX Pragma.

الخيار الإضافي هو الاحتفاظ بـ propeties (أو props لمشجعي التفاعل) ككلمة مخصصة لتمرير الملكية

منذ إصدار 17.0 اليوم ، هل يمكننا تحديث هذه المشكلة لتعكس حالة وقت معالجة ذلك؟

نعم. لقد خططنا في الأصل أن تكون React 17 إصدارًا مع إزالة الكثير من الإهمالات (ومع ميزات جديدة). ومع ذلك ، ليس من الواقعي أن تقوم قواعد الكود القديمة بتحديث جميع التعليمات البرمجية الخاصة بها ، ولهذا السبب قررنا إخراج React 17 التي تركز فقط على تغيير فاصل واحد مهم (يتم إرفاق الأحداث بالعنصر الجذر بدلاً من المستند ). هذا حتى يمكن للتطبيقات القديمة البقاء على React 17 إلى الأبد وتحديث أجزاء منها فقط إلى 18+.

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

لست متأكدًا من أحدث إجماع من مجتمع WC بشأن أي من هذه الخيارات هو الأفضل. من المفيد جدًا أن يتم تدوينها جميعًا (دعائم كبيرة لـ robdodson للقيام بهذا العمل). أشعر بالفضول لمعرفة ما إذا كانت آراء الناس حول هذه الخيارات قد تطورت منذ كتابة هذا الموضوع ، وما إذا كانت هناك أي معلومات جديدة يمكن أن تساعدنا في اختيار الاتجاه.

لا أعتقد أن مجتمع WC قد غير خياره المفضل ، والذي لا يزال الخيار 3. يمكن لـ developit التحدث أكثر عن كيفية توافق Preact مع العناصر المخصصة ، وهو ما قد يكون مثيرًا للاهتمام لـ React أيضًا. للحصول على نظرة عامة حول كيفية توافق الأطر مع تمرير البيانات (المعقدة) إلى عناصر مخصصة ، يحتوي https://custom-elements-everywhere.com/ على جميع التفاصيل.

لاحظ أنه في https://github.com/vuejs/vue/issues/7582 ، اختار Vue استخدام علامة sigil ، واختاروا "." كبادئة (وليس "@" Glimmer).

في https://github.com/vuejs/vue/issues/7582#issuecomment -362943450 ، اقترح trusktr أن تطبيق SSR الصحيح هو عدم عرض خصائص sigil'd كسمات في SSR'd HTML ، وإلى بدلاً من ذلك ، قم بتعيينها كخصائص عبر JS أثناء الترطيب.

أعتقد أنه من غير المحتمل أن نقدم صيغة JSX جديدة من أجل هذه الميزة بالذات وحدها.

هناك أيضًا سؤال حول ما إذا كان الخيار (3) يستحق القيام به إذا كان من المحتمل أن يكون هناك إصدار أكثر عمومية من الخيار (5) على الطاولة. يمكن أن يكون الخيار (5) آلية منخفضة المستوى للإعلان عن عقد React مخصصة منخفضة المستوى مع سلوك تثبيت / تحديث / إلغاء تحميل / ترطيب مخصص. ليست خاصة بالعناصر المخصصة في حد ذاتها (على الرغم من أنها ستكون إحدى حالات الاستخدام).

بدلاً من تقديم صيغة JSX جديدة كليًا لهذه الميزة المحددة ، ماذا عن تقديم JSX أكثر عمومية واستخدامها لتعريف الخصائص المخصصة؟

اقترحت إضافة بناء جملة الخاصية المحسوبة لـ ECMAScript إلى JSX منذ وقت طويل (facebook / jsx # 108) وأعتقد أنها ستكون إضافة مفيدة إلى بناء الجملة بشكل عام.

إذا كان بناء جملة الخاصية المحسوبة متاحًا ، فمن شأنه أن يترك إمكانية تعريف الخصائص باستخدام بناء جملة الخصائص المحسوبة والرموز أو السلاسل ذات البادئة مفتوحة.

على سبيل المثال:

import {property} from 'react';
// ...
<custom-img [property('src')]="corgi.jpg" [property('hiResSrc')]="[email protected]" width="100%">

dantman كيف وترطيبه ؟

لا أعتقد أن أي شخص في WC يريد الخيار 5.

إنها حقًا لا تختلف عن الممارسة الحالية المتمثلة في تصحيح كتابة غلاف React مخصص للعناصر المخصصة. الجانب السلبي الهائل لهذا النهج هو أنه يضع عبئًا على مؤلف المكون لحالة خاصة React أو المستهلك المكون لعناصر مخصصة لحالة خاصة ، ولا يجب أن يكون أي منهما ضروريًا.

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

gaearon لا أعرف ما يكفي من الترطيب والخصائص المخصصة لمعرفة ما هو مطلوب ، هذا في الأساس اقتراح بناء الجملة.

الفكرة العامة هي أن property(propertyName) يمكن ، بناءً على الطريقة التي ترغب في تنفيذها ، إخراج سلسلة مسبوقة (على سبيل المثال '__REACT_INTERNAL_PROP__$' + propertyName ) أو إنشاء رمز وحفظ ارتباط "رمز => propertyName" في خريطة.

قد يكون لاحقًا مشكلة إذا كنت بحاجة إلى توصيل تلك الخريطة إلى العميل.

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

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

لا أحد يفوز بالخيار 5. 😕

claviska هل لديك أي آراء حول كيفية عمل عرض الخادم

سيتم تقسيم gaearon SSR إلى حالتين: تلك التي يدعم فيها العنصر المخصص SSR وتلك التي لا يدعمها.

بالنسبة للعناصر التي لا تدعم SSR ، لا يهم تعيين الخصائص على الخادم. باستثناء خصائص الانعكاس المضمنة مثل id و className ، يمكن إسقاطها وكتابتها فقط على العميل.

بالنسبة للعناصر التي تدعم خصائص SSR ، ستكون مهمة ، ولكن فقط حتى تتمكن من تشغيل أي نتيجة تسببها على DOM. يتطلب هذا مثيل عنصر أو نوعًا من وكيل / احتياطي SSR ، وبعض البروتوكولات لتوصيل حالة SSR'ed DOM. لا توجد واجهة مشتركة من جانب الخادم لهذه العملية حتى الآن ، لذلك لا يوجد شيء يمكن القيام به هنا في الوقت الحالي. سيحتاج مؤلفو مكوّنات الويب ومسؤولو صيانة المكتبات إلى اكتشاف بعض الأشياء قبل أن تتمكن React من بناء أي جسور هناك.

في عمل فريقي على SSR ، قمنا بالتكامل مع React عن طريق تصحيح createElement واستخدام dangerouslySetInnerHTML . أعتقد أن هذا هو مستوى التكامل / التجريب الذي سنصل إليه قليلاً. في مرحلة ما قريبًا ، آمل أن نتمكن من الالتقاء ببعض بروتوكولات أرض المستخدم من أجل التشغيل المتداخل داخل أنظمة SSR. حتى ذلك الحين ، من الآمن والحكيم تمامًا أن يكون لديك خاصية عنصر مخصص ودعم الحدث بدون _deep_ SSR. ستظل علامة العنصر SSR'ed باعتبارها تابعة لمكون React كما هي اليوم.

باستثناء خصائص الانعكاس المضمنة مثل id و className ، يمكن إسقاطها وكتابتها فقط على العميل.

هل يمكنك مساعدتي في فهم كيف يعمل هذا؟ على سبيل المثال ، لنفترض أن هناك <github-icon iconname="smiley" /> . هل تقصد أن SSR يجب أن يتضمن فقط <github-icon /> في استجابة HTML ، وبعد ذلك سيقوم React بتعيين domNode.iconname = ... أثناء الترطيب؟ في هذه الحالة ، لست متأكدًا من فهمي لما يحدث إذا تم تحميل تنفيذ العنصر المخصص قبل حدوث ترطيب React. كيف سيعرف تطبيق github-icon الرمز الذي سيتم عرضه إذا لم يكن iconname موجودًا في HTML؟

لا توجد واجهة مشتركة من جانب الخادم لهذه العملية حتى الآن ، لذلك لا يوجد شيء يمكن القيام به هنا في الوقت الحالي. سيحتاج مؤلفو مكوّنات الويب ومسؤولو صيانة المكتبات إلى اكتشاف بعض الأشياء قبل أن تتمكن React من بناء أي جسور هناك.

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

gaearon إذا كان تحميل تنفيذ العنصر المخصص قبل حدوث ترطيب React ، فسيتم تعيين قيمة دافولت مهما كانت قيمة السمة iconname . ماذا تقصد ب if _iconname_ does not exist in the HTML ؟ إذا لم يتم تحديد سمة لنوع HTMLElement ، فسوف يتجاهلها. بمجرد تحميل تعريف العنصر المخصص ، سيتم توسيع نوع HTMLElement وتعريف iconname وسيكون قادرًا على الاستجابة لقيمة جديدة يتم تمريرها.

أحاول فهم هذا من منظور المستخدم. نحن نعرض صفحة على الخادم. يوجد رمز في منتصف النص. يتم تنفيذ هذا الرمز كعنصر مخصص. ما هو تسلسل الأشياء التي يجب أن يواجهها المستخدم النهائي؟

ما أفهمه حتى الآن هو أن:

  1. يرون نتيجة العرض الأولية. سيتضمن كل الترميز العادي ، لكنهم لن يروا العنصر المخصص <github-icon> على الإطلاق. من المفترض أنه سيكون ثقبًا ، مثل div فارغ. أرجوا أن تصحح لي إذا كنت مخطئا (؟). لم يتم تحميل تنفيذه بعد.

  2. يتم تحميل تطبيق العنصر المخصص <github-icon> ويتم تسجيله. إذا فهمت بشكل صحيح ، فهذه هي العملية التي تسمى "الترقية". ومع ذلك ، على الرغم من أن JS جاهزة ، إلا أنها لا تزال غير قادرة على إظهار أي شيء لأننا لم نقم بتضمين iconname في HTML. لذلك ليس لدينا المعلومات الخاصة بالرمز الذي سيتم عرضه. هذا لأننا قلنا سابقًا أنه "يمكن إسقاط الخصائص غير المضمنة من HTML". لذلك لا يزال المستخدم يرى "حفرة".

  3. رد الفعل وتحميل كود التطبيق. يحدث الترطيب. أثناء الترطيب ، تعيِّن React الخاصية .iconname = وفقًا للإرشاد. يمكن للمستخدم رؤية الرمز الآن.

هل هذا تفصيل صحيح للحالة التي يتم فيها تحميل تطبيق JS للعنصر المخصص أولاً؟ هل هذا هو السلوك المرغوب فيه لمجتمع المراحيض؟

gaearon نعم هذا ما أتوقع حدوثه في هذه الحالة.

من ناحية أخرى ، لقد مرت ثلاث سنوات ، وأعتقد أنك تقول إن هذا الإجماع لم يتشكل بعد

أنا لا أقول أن الإجماع لم يتحقق. أقول إنه لا داعي للقلق بشأن _deep_ SSR في الوقت الحالي ، ولا ينبغي أن تدع المخاوف الغامضة بشأنه تحظر أبسط قابلية التشغيل البيني من جانب العميل والتي يمكن تحقيقها وتكون مفيدة للغاية في الوقت الحالي.

لم أر هذا التمييز من قبل (عميق مقابل ضحل) لذا دعني أحاول إعادة التأكيد عليه للتحقق مما إذا كنت أفهمك.

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

من خلال SSR "غير العميق" ، أعتقد أنك تقول أننا وضعنا علامة CE نفسها في HTML. دون القلق مما تقرر. هذا منطقي بالنسبة لي أيضا. كان سؤالي حول _ هذا_ التدفق على الرغم من - وليس حول SSR "العميق".

على وجه الخصوص ، يصف https://github.com/facebook/react/issues/11347#issuecomment -713230572 موقفًا حيث حتى عندما _ بالفعل _ تم تنزيل منطق CE ، ما زلنا غير قادرين على إظهار أي شيء للمستخدم حتى الماء. تصبح خصائصه غير معروفة حتى يتم تحميل رمز عميل JS الخاص بالتطبيق بالكامل ويحدث الترطيب. أنا أسأل ما إذا كان هذا هو بالفعل السلوك المرغوب.

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

تضمين التغريدة

أعتقد أن https://github.com/facebook/react/issues/11347#issuecomment -713230572 قد لا يكون أفضل مثال على هذه الميزة.

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

يمكن بسهولة تحقيق الحالة التي وصفتها فقط باستخدام iconname كسمة مباشرة وستظل إلى حد كبير نفس النتيجة النهائية المقدمة دون انتظار الماء.

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

أما بالنسبة لما ذكرته هنا ، فبناءً على كيفية تنفيذ المكون ، يمكنك تجنب هذه المشكلة المتمثلة في رؤية "ثقب".

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


أعتقد أن هذه الميزة ستكون مفيدة في الغالب لاستخدام مكونات أكثر تعقيدًا لها خصائص مثل الكائنات ، والمصفوفات ، والوظائف ، وما إلى ذلك.

خذ على سبيل المثال ، المكون الافتراضي lit-virtualizer scroller.

لهذا للعمل بشكل صحيح أنه يتطلب items مجموعة و renderItem ظيفة ويمكنك حتى اختياريا تعيين scrollTarget عنصر، والتي يمكن وضعها إلا في رد فعل باستخدام الحكام فى الحال.

في حالة مثل هذه ، من المحتمل أن تقوم بتحميل المحتوى بنوع من ترقيم الصفحات أو التحميل البطيء على أي حال ، لذا قد لا يكون لديك أي محتوى حتى خطوة الترطيب في حالة SSR بهذه المشكلة.

gaearon يرجى ملاحظة أن العناصر المخصصة هي معيار DOM وبالتالي لا يوجد "مجتمع WC" في حد ذاته بمعنى أن كل من يستخدم العناصر المخصصة يستخدمها بنفس الطريقة. يتم دمج العناصر المخصصة بطريقتها الخاصة لكل مطور ، لأنها بطبيعتها بدائية منخفضة المستوى يعتمد عليها الأشخاص.

ومع ذلك ، ظهرت أنماط عديدة بمرور الوقت وجميع الأطر الشائعة (باستثناء React) تنفذ بعض الحلول لتوفير التوافق مع معيار DOM هذا. كما ترى على https://custom-elements-everywhere.com/ ، اختارت جميع الأطر / المكتبات (باستثناء React) خيارات مختلفة. في هذه المشكلة ، يتم سرد الخيارات المختارة كخيارات 1 و 2 و 3. لا يوجد إطار عمل / مكتبة تنفذ حاليًا الخيار 4 أو 5 ولا أعتقد أنه من المستحسن تنفيذها.

لذلك ، أقترح أن تتبع React حذوها مع الأطر / المكتبات الأخرى وتختار خيارًا أثبت فعاليته ، على سبيل المثال من الخيارات 1-3. لا أعتقد أن React بحاجة إلى إعادة اختراع العجلة هنا عن طريق اختيار الخيار 4 أو 5 ، والذي ليس لدينا بيانات عنه هو حل قابل للصيانة على المدى الطويل إما لـ React أو تلك التي تعتمد على معايير DOM.

لذلك ، من خلال عملية الحذف (مع التعليقات المرتبطة أدناه) ، نظرًا لأن الخيار 3 لن يتم إجراؤه على JSX وتم وضع علامة على الخيارين 4 و 5 على أنهما غير مرغوب فيهما بواسطة WC في هذا الموضوع ، فنحن عالقون مع 1 أو 2 .

ونظرًا لأن الرقم 1 يبدو أنه يحتوي على عيوب لا يمكن تحملها ، فيبدو أن الخيار 2 هو


لا يوجد إطار عمل / مكتبة تنفذ حاليًا الخيار 4 أو 5 ولا أعتقد أنه من المرغوب فيه تنفيذها.

( @ TimvdLippe في https://github.com/facebook/react/issues/11347#issuecomment-713474037)

أعتقد أنه من غير المحتمل أن نقدم صيغة JSX جديدة من أجل هذه الميزة بالذات وحدها.

( gaearon في https://github.com/facebook/react/issues/11347#issuecomment-713210204)

سيكون ذلك منطقيًا بالنسبة لي ، نعم. شكرا على الملخص! 😄

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

أنا لا أتابع تمامًا. كان السيناريو الافتراضي الخاص بي عبارة عن رد على https://github.com/facebook/react/issues/11347#issuecomment -713223628 والذي بدا وكأنه اقتراح بأنه لا ينبغي لنا إصدار سمات في HTML الذي تم إنشاؤه بواسطة الخادم على الإطلاق ، باستثناء id و class . لا أعرف ما يعنيه "استخدام اسم الرمز كسمة فقط" - هل تقول أنك ترغب في رؤية سمات HTML _include_ الأخرى التي ينشئها الخادم؟ يبدو أن هذا يتعارض مع ما قيل للتو في وقت سابق. أعتقد أنه سيكون من المفيد حقًا أن يقدم كل رد صورة كاملة لأنه بخلاف ذلك سنستمر في الحلقات. سؤالي لكم هو:

  1. ما يتم تسلسله بالضبط في HTML الذي تم إنشاؤه بواسطة الخادم في السيناريو الذي وصفته
    أ. في حالة <github-icon iconname="smiley" />
    ب. في الحالة التي تحدثت عنها ، على سبيل المثال <github-icon icon={{ name: "smiley" }} />
  2. ما يسمى DOM API على العميل أثناء الترطيب في أي من هاتين الحالتين

شكرا!

هل تم اعتباره خيارًا لإنشاء رقاقة ، واستبدال React.createElement() بتطبيق مخصص ، ما الذي يتم تعيين الخصائص بداخله؟

مثال على الاستخدام:

/** <strong i="8">@jsx</strong> h */
import { h } from 'react-wc-jsx-shim';

function Demo({ items }) {
   return <my-custom-list items={items} />
}

مشروع التنفيذ:

export function h(element, props, children) {
   if(typeof element === 'string' && element.includes('-')) {
      return React.createElement(Wrapper, { props, customElementName: element }, children)
   }
   return React.createElement(element, props, children);

}

function Wrapper({customElementName, props}) {
   const ref = React.useRef();
   React.useEffect(() => {
      for(const prop in props) {
         ref.current[prop] = props[prop];
      }
   });
   return React.createElement(customElementName, { ref, ...props });
}

أعلم أن هذه ليست ميزة مضمنة ، ولكن أعتقد أنه يجب إلغاء حظر المستخدمين بنفقات منخفضة جدًا.

@ just-boris هو في الأساس ما تفعله التطبيقات أو المكتبات الآن ، إما باستخدام تصحيح createElement أو غلاف. تحتاج أيضًا إلى استبعاد أسماء الخصائص ذات الأحرف الخاصة في React. لا أعتقد أن هناك قائمة تم تصديرها ، لذا فهم فقط يرمزون إلى denylist مثل ['children', 'localName', 'ref', 'elementRef', 'style', 'className'] .

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

سأكون في الواقع أكثر اهتمامًا بالأحداث من إصلاح القطاع الأمني ​​(SSR). لا تملك React طريقة لإضافة معالجات الأحداث ، وهذه فجوة كبيرة في إمكانية التشغيل البيني مع واجهات برمجة تطبيقات DOM الأساسية.

هل تم اعتباره خيارًا لإنشاء رقاقة ، مع استبدال React.createElement () بتطبيق مخصص ، ما الذي تقوم الخصائص بتعيينه بالداخل؟

كما ذكر Rob في الإصدار الأصلي ، لقد جربت هذا في الماضي عبر https://github.com/skatejs/val ، لذا فإن وجود برنامج JSX pragma المخصص الذي يغطي React.createElement هو أمر قابل للتطبيق - ربما على المدى القصير - الحل.

لدي أيضًا فرع ويب في Skate ينفذ كلًا من ما يشار إليه باسم SSR العميق والضحل ، على وجه التحديد لـ React. الدروس المستفادة من هذا العمل حتى الآن ، هي أنه لا يمكنك الحصول على غلاف JSX واحد لجميع المكتبات إذا كنت تريد عمل SSR عميقًا لأن كل مكتبة تعتمد على واجهات برمجة التطبيقات والخوارزميات الخاصة بها للقيام بذلك. (بالنسبة للسياق ، تحتوي Skate على جزء أساسي مخصص من مكتبتها وطبقات صغيرة مصممة لدمج كل مكتبة شائعة في السوق لجعل الاستهلاك والاستخدام متسقين في جميع المجالات.)


لم أعد أعمل كثيرًا في المصادر المفتوحة ، ولم أعد أعمل على تويتر أيضًا ، لذا لا تتردد في أخذ رأيي بحذر.

يبدو أن الخيار 1 موجود بصفته مدافع الشيطان عن الخيار 2.

يبدو الخيار 2 وكأنه الطريق للذهاب. إنه قريب مما فعلته Preact ، لذلك هناك سابقة وإمكانية لمعيار مجتمع (والذي أعتقد أنه سيكون من الرائع القيام به على أي حال ؛ أظهرت JSX أن هذا يمكن أن ينجح) ، وهي أيضًا خطوة براغماتية لـ React من حيث سهولة الترقية (على عكس الخيار 1).

يبدو الخيار 3 جيدًا على الورق ، لكنني أعتقد أنه من الناحية اللوجستية سيكون أكثر صعوبة من الخيار 2 بسبب النفقات المعرفية ، والتوثيق حول النفقات العامة المذكورة ، والمجهول باستخدام SSR.

كما ذكرنا سابقًا ، كنت قد قدمت في الأصل الخيار 4 ولكن بعد التفكير ، لست متأكدًا من أنني أحبه بعد الآن. يمكنك تغييره ليكون أكثر قبولًا ، حيث تحدد صريحًا props و events (بدلاً من attrs ) ، ولكن حتى ذلك الحين يتطلب الخيار 2 معرفة أقل بتفاصيل التنفيذ ولا يوجد شيء يضطر أي شخص لتغييره لتبنيه.

يبدو الخيار 5 وكأننا نتجاهل المشكلة الأساسية تمامًا.


جانبا ، أنا سعيد للغاية برؤية هذا الأمر وآمل أن تكونوا بخير!

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

سيكون من الأسهل بكثير إقناع فريق React الأساسي بإضافة ميزة إذا كانت موجودة بالفعل كوحدة طرف ثالث شائعة وقابلة للتطبيق.

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

لا أعتقد أن هذا شيء يمكن تصحيحه [بدقة] من الخارج. معظم الحلول يوزرلاند هي مغلفة مثل هذا و هذا . بدون تعديل React ، لا يمكنني التفكير في بديل معقول لهذا النهج ، والتفاف بالتأكيد ليس حلاً مثاليًا. 😕

لاحظ أنه في vuejs / vue # 7582 ، اختار Vue استخدام sigil ، واختاروا "." كبادئة (وليس "@" Glimmer).

ليس لدي رابط لبيان رسمي بشأن هذا (وربما يمكن لشخص أقرب إلى Vue تأكيده صراحة) ، ولكن يبدو أن Vue قد انتقل إلى الخيار 2 اعتبارًا من Vue 3.0 ، مما يعني أنه يتصرف بشكل مشابه لـ Preact. (راجع هذه المشكلة للاطلاع على السياق).

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

هل يمكنك الرد على الأسئلة المحددة في https://github.com/facebook/react/issues/11347#issuecomment -713514984؟ أشعر وكأننا نتحدث عن بعضنا البعض. أريد فقط أن أفهم السلوك المقصود بأكمله - بطريقة محددة. ما يتم تعيينه ومتى يتم إجراء تسلسل في هذه الحالة.

بصفتي مطورًا عشوائيًا لـ Preact + WC الذي تعثر هنا ، أردت أن أشير إلى أن "الخيار 2" ليس فقط _تغييرًا فاصلاً _ ، ولكنه أيضًا _حل غير كامل _ (لا يزال بإمكان Preact التفاعل بشكل إعلاني فقط مع مجموعة فرعية من مكونات الويب الصالحة).

حتى كمستخدم حالي للإرشاد ، فإن هذا يبدو غير مرغوب فيه على المدى الطويل.


لا يستطيع برنامج Preact الاسترشادي ("الخيار 2") تعيين الخصائص التي لها معنى خاص في React (مفتاح ، أطفال ، إلخ) أو Preact (أي شيء يبدأ بـ on ).

أي بعد التقديم أدناه JSX:

<web-component key={'key'} ongoing={true} children={[1, 2]} />

الخصائص key ، ongoing و children ستكون جميعها undefined (أو أيًا كانت القيمة الافتراضية) في المثيل الذي تم إنشاؤه web-component .

أيضًا ، على عكس OP ، يعد هذا الخيار أيضًا تغييرًا جذريًا. توفر معظم مكونات الويب (على سبيل المثال مصنوعة من lit-element ) القدرة على تمرير البيانات الغنية المتسلسلة عبر السمات ، بغرض استخدامها مع HTML خالص. يمكن تقديم مثل هذه المكونات من React مثل ذلك

<web-component richdata={JSON.stringify(something)} />

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

أخيرًا ، يتمتع مؤلف Web Component بحرية إرفاق دلالات مختلفة بمهارة إلى السمة والخصائص التي تحمل الاسم نفسه. قد يكون أحد الأمثلة على ذلك هو مكون الويب الذي يحاكي سلوك العنصر الأصلي input - معاملة السمة value كقيمة أولية ، ومراقبة التغييرات فقط على الخاصية value . لا يمكن التفاعل مع مثل هذه المكونات بشكل كامل عبر jsx مع النهج التجريبي ، ويمكن أيضًا أن تتعرض لكسر دقيق إذا تم تقديمها.

أعتقد أنه من غير المحتمل أن نقدم صيغة JSX جديدة من أجل هذه الميزة بالذات وحدها.

ماذا عن استخدام مساحات الأسماء؟ يقترح https://github.com/facebook/jsx/issues/66 إضافة مساحة اسم react لـ key و ref . على نفس المنوال ، هل سيكون شيء مثل react-dom مساحة اسم جيدة لصكها لتحديد خصائص DOM؟ باستخدام مثال الخيار 3 في OP ، سيكون ذلك:

<custom-img react-dom:src="corgi.jpg" react-dom:hiResSrc="[email protected]" width="100%">

هذا ليس الأكثر راحة. فقط dom سيكون أفضل ، لكن لست متأكدًا مما إذا كانت React تريد سك مساحات الأسماء التي لا تبدأ بـ react . أيضًا ، بيئة العمل السيئة في هذا ليست نهاية العالم ، إذا كانت الفكرة هي أن الإعداد كخصائص يجب أن يكون الحالة الأقل شيوعًا. يعد استخدام السمات أفضل ، حيث يوفر ذلك التكافؤ مع SSR. الإعداد كخصائص هو عندما تكون السمات إشكالية (مثل تمرير كائن أو لخصائص لا تدعمها سمات) ، ولهذه الخصائص الإشكالية بالتحديد لا يمكننا SSR لها سمات على أي حال ، وسوف نحتاج إلى ترطيبها عبر JS.

حل غير كامل

(لا يزال بإمكان Preact التفاعل بشكل إعلاني فقط مع مجموعة فرعية من مكونات الويب الصالحة)

brainlessbadger ، هل يمكنك أيضًا تعديل تعليقك أعلاه لتضمين ما هي هذه المجموعة الفرعية في الواقع؟ على سبيل المثال. ما هي مكونات الويب / العناصر المخصصة المتأثرة (مع أمثلة)؟ وكيف تتأثر بالضبط؟

karlhorky أضفت شرحًا. آسف لكونك غامضة بلا داع.

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

هذه مشكلة للسمات والخصائص أيضًا حيث يمكن إضافة سمات جديدة إلى HTMLElement مثل كل هذه: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes يبدو أن هناك زوجًا من المضافة حديثًا أيضًا ، لذا لا تزال هناك عناصر جديدة تتم إضافتها.

أعتقد أنه بالمعنى الدقيق للكلمة يجب عليك استخدام - في اسم أي سمة مخصصة أو حدث مخصص.

أي شيء آخر هو حل وسط يوازن بين مخاطر هذا المكون الذي يمنع المواصفات المستقبلية من استخدام اسم جميل.

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

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

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

أعتقد أنه يجب عليك بالمعنى الدقيق للكلمة استخدام - باسم أي سمة مخصصة أو حدث مخصص.

لا تتضمن مواصفات العنصر المخصص مثل هذه القيود ، لذا فإن تطبيقها في React سيؤثر بشكل كبير على قابلية التشغيل البيني.

لا ينبغي أن يُتوقع من مؤلفي العناصر المخصصة الاشتراك في المتطلبات التعسفية لإطار العمل. تخيل أن كل إطار يقوم بذلك مع اختلاف الآراء والاتفاقيات. هذا يلغي الغرض من استخدام مكونات الويب. 😕

من الناحية المثالية ، يجب أن يتكيف الإطار لاستيعاب المعيار.

في الواقع. setAttribute() و dispatchEvent() هي فقط واجهات برمجة تطبيقات خاصة لا تتعلق بمكونات الويب والتي سمحت بأسماء عشوائية منذ إنشائها. يمكن لأي عنصر أن يكون له أي خاصية وأن يطلق أي حدث - إنها مجرد حقيقة أساسية لعنصر DOM.

تمت إضافة مساحة الاسم data- لسبب ما. هناك فرق بين ما يمكنك فعله تقنيًا وأفضل الممارسات. يمكنك أيضًا تصحيح النماذج الأولية تقنيًا ولكن بعد ذلك تحصل على مواقف / تتضمن.

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

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

على الرغم من أنني أعتقد بشكل ملموس أن هذا سيؤدي إلى مشكلة في الأساليب الحالية التي يستخدمها الأشخاص مع SSR + AMP نظرًا لأن ذلك يستخدم سمات ويمكنك افتراض أن وقت تشغيل AMP قد تم تحميله بالفعل.

بافتراض عدم إغلاق الباب في الخيار 3 ، فإنه يتمتع بميزة كبيرة على الخيار 2 ، غير مدرج في العيوب أعلاه - المشكلة التي وجدتها مع الخيار 2 هي أنه إذا تم تحميل مكتبات مكونات الويب بشكل غير متزامن ، فقد لا يكون الأمر كذلك تعرف ، بالنسبة لعنصر غير معروف ، أن "الخاصية" ستكون خاصية. نظرًا لأنه لا يعثر على الخاصية الموجودة في العنصر غير المعروف ، فإنه يتم تعيينه افتراضيًا على سمة. الحل هو عدم عرض هذا المكون ، حتى يتم تحميل مكتبات مكونات الويب التابعة ، وهي ليست أنيقة للغاية (أو من حيث الأداء المثالي). نظرًا لأن مجموعتي تستخدم asp.net ، وليس node.js ، لم أستكشف مطلقًا SSR حقًا ، لذا فإن الملاحظات أدناه تخمينية.

أعتقد أنها لفتة لطيفة ، من جانب فريق React ، لاقتراح تجاوز ما تدعمه الأطر الأخرى (على حد علمي) ، بقدر ما هو SSR ، مما يسمح بتمرير خصائص الكائن أثناء العرض الأولي ، والذي يمكن أن يخدم مستخدم أفضل.

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

تستخدم AMP اصطلاحًا آخر ، على الرغم من ذلك - فهي تستخدم script type = application.json للقيام بذلك ، وهو بديل معقول (ولكنه مطوّل).

لكن التمسك بنهج السمة:

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

لذلك لتجنب تأخير الماء ، سيكون من الملائم ضبط:

<github-icon icon='{"name":"smiley"}'></github-icon>

خلال SSR. بعد ذلك ، يمكن لـ github-icon أن يقوم بعمله على الفور ، ويقوم داخليًا بإجراء JSON.parse للسمة ، ولا يتعين عليه انتظار تمرير React في قيمة الكائن (الأكثر اكتمالًا؟).

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

بالطبع ، بعض الخصائص عبارة عن كائنات غير قابلة للتجميد / التحليل ، لذلك لا ينطبق هذا ، وستحتاج هذه الخصائص إلى انتظار اكتمال الترطيب.

إذا اتبعت جميع الخصائص والسمات اصطلاح التسمية المفضل لدى فريق React (ربما) - تحتوي جميع السمات على شرطات ، وكانت جميع الخصائص عبارة عن أسماء مركبة باستخدام حالة الجمل ، فربما يساعد وجود شرطة في التمييز بين السمات والخصائص:

<github-icon my-icon={myStringifiedProperty} myIcon={myObjectProperty}></github-icon>

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

يمكن أن تفترض React فقط أنه إذا كان مفتاح السمة / الخاصية هو حالة الجمل ، لتمريره دائمًا ككائن من جانب العميل ، وتسلسل كائن مرتبط بـ JSON إذا تم تعيينه أثناء SSR. وبالمثل ، يمكن للشرطات الموجودة في المفتاح (بأمان ، على ما أعتقد) أن تفترض أنها سمة ، وتمرر فقط .toString () من القيمة. لكن أعتقد أن هذا يفترض الكثير. كما أن عدم دعم سمات وخصائص الكلمة المفردة ، والذي يعتبر HTML صالحًا إذا تم تطبيق السمات على مكون ويب يمتد HTMLElement ، سيكون مقيدًا للغاية. أنا أؤيد قيام W3C بإصدار قائمة بأسماء السمات "المحجوزة" التي قد تستخدمها في المستقبل ، على غرار الكلمات الرئيسية المحجوزة لـ JS ، وإيجاد طرق لإيجاد طرق لتحذير المطورين إذا كانوا يستخدمون اسم سمة محجوز بشكل غير صحيح.

لكنني أعتقد أن الخيار 3 هو أفضل نهج. ومع ذلك ، إذا كان من الممكن تحسينه ، كما اقترح gaearon ، للحصول على تجربة مستخدم أفضل ، فسيكون ذلك رائعًا.

اقتراحي سيكون:

<github-icon icon={myDynamicIcon}/>

تعني السمة (toString ()).

<github-icon icon:={myDynamicIcon}/>

قد يعني - أثناء SSR ، تجاهل ، لكن اربط العميل بخاصية الكائن (بعد الترطيب).

الآن ماذا عن السيناريو (بعض؟) يهتم فريق React بحلها؟ كان أول ما فكرت به هو مجرد علامة سيجيل أخرى ، مثل نقطتين:

<github-icon icon::={myDynamicIcon}/> //Not my final suggestion!

قد يعني ، خلال SSR ، JSON.stringify الخاصية ، وتعيينها كسمة في HTML الذي تم تقديمه ، وتمريرها ككائن على العميل عندما تكون الخاصية مرتبطة بالتغييرات بعد الماء.

هذا يترك الموقف الصعب لما يجب فعله بالأسماء المركبة. أي إذا حددنا:

<github-icon iconProps::={myDynamicIconProp}/>  //Not my final suggestion!

لم يكن مثيرًا للجدل في الماضي أن تكون السمة المقابلة لـ iconProps هي icon-props.

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

الاقتراح الوحيد (القبيح؟) الذي يمكنني طرحه هو:

<github-icon icon-props:iconProps={myDynamicIconProp}/>

وهو ما يعني ، على الخادم ، استخدام رمز الخاصية المميزة بعد التسلسل ، وعلى العميل استخدام رمز الخاصية ، تمرير الكائنات مباشرة.

فائدة أخرى محتملة (لقطة طويلة؟) للتدوين الأكثر تفصيلاً ، مما يسمح بزوج خاصية / خاصية مختلطة ، هي: قد يكون من الأسرع قليلاً تعيين خصائص العنصر الأصلي بشكل متكرر ، بدلاً من السمة المقابلة ، خاصةً بالنسبة الخصائص التي ليست سلاسل. إذا كان الأمر كذلك ، فهل تستخدم React حاليًا سمات على الخادم وخصائص على العميل؟ إذا لم يكن الأمر كذلك ، فهل يرجع ذلك إلى نفس مشكلة صعوبات الترجمة في التسمية ، والتي يمكن أن يحلها هذا الترميز؟

bahrus أعتقد أنه يمكن تبسيطه

<my-element attr='using-quotes' property={thisIsAnObject} />

أعتقد أنه قد يكون من الأفضل توضيح المشكلة بمثال ملموس.

يحتوي عنصر نموذج HTML على عدد من السمات. لا يبدو أن جميع الأسماء التي تحتوي على "أسماء مركبة" تتبع نمط تسمية ثابتًا - فهي تلتصق عمومًا بأحرف صغيرة ، ولا توجد فواصل ، ولكن في بعض الأحيان يوجد فاصل شرطة - "Accept-charset" على سبيل المثال ، وأحيانًا لا - - "نوفاليدات".

لا يتناسب اسم خاصية JS المطابق مع نمط عام لطيف أيضًا - AcceptCharset و noValidate. السمة noValidate property / novalidate هي قيمة منطقية ، لذلك بالنسبة للعميل ، سيكون من الضياع (أتخيل) القيام بـ myForm.setAttribute ('novalidate'، ') على عكس myForm.noValidate = صحيح.

ومع ذلك ، على الخادم ، ليس من المنطقي تعيين myForm.noValidate = true ، لأننا نريد إرسال سلسلة تمثيل لـ DOM ، لذلك نحتاج إلى استخدام السمة:

<form novalidate={shouldNotValidate}>

في الواقع ، ليس من الواضح بالنسبة لي أن React / JSX لديها طريقة عالمية لتعيين سمة منطقية بشكل مشروط ، بالاعتماد ، ربما ، على جدول بحث ثابت وثابت ، والذي يبدو (؟) جامدًا للغاية . إذا كنت جريئًا جدًا ، فهذا يبدو وكأنه مجال آخر يمكن أن يتحسن فيه React / JSX ، ليكون متوافقًا تمامًا مع الطريقة (الفوضوية) التي يعمل بها DOM ، كجزء من RFC؟

كيف يمكننا تمثيل كل هذه السيناريوهات بحيث يكون للمطور سيطرة كاملة على الخادم (عبر السمات) والعميل (عبر الخصائص) دون التضحية بالأداء؟ في هذه الحالة المنطقية مثل novalidate ، أقترح:

<form novalidate:noValidate?={shouldNotValidate}/>

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

يبدو لي أن إضافة دعم لتسلسل خصائص الكائن اختياريًا إلى سمات عبر JSON.stringify على الخادم ، سيكون بمثابة ربح إضافي كبير لمكونات React والويب.

أم هل فاتني شيء؟ ( eavichay ، كيف تقترح تمثيل هذه السيناريوهات بشكل أفضل ، وليس اتباع

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