React: تحذير غير متوقع عند الترطيب بالبوابة و SSR

تم إنشاؤها على ١٥ أبريل ٢٠١٨  ·  24تعليقات  ·  مصدر: facebook/react

هل تريد طلب ميزة أو الإبلاغ عن خطأ ؟

خلل برمجي

ما هو السلوك الحالي؟

بالنظر إلى المقتطف (المبسط) التالي:

class HoverMenu extends React.Component {
  render() {
    if (typeof document === 'undefined') return null
    const root = document.getElementById('root')
    return ReactDOM.createPortal(<div>Hello World</div>, root)
  }
}

class Para extends React.Component {
  render() {
    return (
      <span>
        Some Text
        <HoverMenu />
      </span>
    )
  }
} 

حيث div#root هو div صالح موجود ، يظهر الخطأ التالي عند الترطيب بعد SSR:

Warning: Expected server HTML to contain a matching <div> in <span>

يختفي التحذير إذا قمت بتحديث تعريف HoverMenu إلى:

class HoverMenu extends React.Component {
  componentDidMount() {
    this.setState({ isActive: true })
  }
  render() {
    const { isActive} = this.state
    if (!isActive) return null
    const root = document.getElementById('root')
    return ReactDOM.createPortal(<div>Hello World</div>, root)
  }
}

أفضل عدم القيام بذلك بسبب العرض المزدوج الناتج عن setState في componentDidMount .

لا أفهم تمامًا ما يخبرني به هذا الخطأ. لا يتم عرض <div /> من جانب الخادم في كلتا الحالتين. الخطأ محير بشكل خاص ، حيث أن HoverMenu DOM div لا يتم عرضه حتى داخل DOM span . (أتساءل عما إذا كان هذا يحدث لأن HoverMenu متداخل داخل React span .)

ما هو السلوك المتوقع؟

لم يتم طرح أي خطأ. أو على الأقل أن رسالة الخطأ أوضح.

ما إصدارات React وأي متصفح / نظام تشغيل متأثر بهذه المشكلة؟

كروم 65
رد فعل 16.2
(SSR حتى 5.1 التالي)

medium Bug good first issue

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

بينما لا يتم دعم بوابات الترطيب (https://github.com/facebook/react/issues/13097) ، فإن الرسالة نفسها ليست منطقية. سنحتاج إلى التحقيق وإصلاحه.

ال 24 كومينتر

لدي مشكلة مماثلة ، والتي يمكن أيضًا حلها عن طريق إعادة العرض على العميل عبر setState.
في حالتي ، أحاول تقديم مشروط داخل البوابة. يُرجع المكون Modal null عند تقديمه على الخادم ويقوم بإنشاء مدخل على العميل. ومع ذلك ، فإن DOM يفسد بعد الماء.

على سبيل المثال ، إذا استخدمته بهذا الشكل داخل مكوني الرئيسي:

<Modal>
This is a test
</Modal>

<div className="some-div-after-the-modal">
</div>

بدلًا من الحصول على هذا بعد الماء:

<!-- Inside the portal container -->
<div class="modal-wrapper">
    <div class="modal-content">This is a test</div>
</div>

<!-- In the main component -->
<div class="some-div-after-the-modal">
</div>

أحصل على هذا:

<!-- Inside the portal container -->
<div class="some-div-after-the-modal">
    <div class="modal-content">This is a test</div>
</div>

<!-- In the main component -->
<div class="some-div-after-the-modal">
</div>

والتحذير هو نفسه ( Expected server HTML to contain a matching <div> in <div> ). أستخدم React 16.3 مع طريقة SSR مخصصة.

لست متأكدًا مما إذا كان هذا هو السلوك المقصود.

بينما لا يتم دعم بوابات الترطيب (https://github.com/facebook/react/issues/13097) ، فإن الرسالة نفسها ليست منطقية. سنحتاج إلى التحقيق وإصلاحه.

gaearon الغرض من الإصلاح هو

  • [] يتم استخدام بوابة الاكتشافات في hydrate () ثم تقوم بإلقاء رسالة خطأ بشكل أكثر ملاءمة من خلال الثابت.
    على سبيل المثال ، invariant violation: Portal is not support on SSR. For more detail, please refer https://github.com/facebook/react/issues/13097
  • [] إضافة اختبار

    • [] إذا تم استخدام البوابة مع الهيدرات () ، يجب أن تلقي رسالة الخطأ أعلاه

حق؟
أنا على استعداد إذا لم يكن الأمر عاجلاً.

أخطط لمشروع SSR Doc إلى موقع الويب الريبو ، لذلك يجب أن أكون على دراية بآلية الترطيب.
أعتقد أن هذا التحقيق سيكون مفيدًا لخطتي.
https://github.com/facebook/react/pull/13379

لماذا لا يتم دعم البوابات على SSR ، حتى لتقديم "لا شيء"؟

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

من المحتمل أن نعود إلى هذا مع تجديد عارض الخادم للتعليق.

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

تستخدم لأشياء مثل الوسائط

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

يأخذون أيضًا عنصر دوم

الحق - في التصميم الحالي. يمكن أن يتغير. https://github.com/facebook/react/pull/8386#issuecomment -262375265

أنا فقط لا أرى أي شيء ذي قيمة من الرمي.

تكمن قيمة الرمي في الاعتراف صراحة بأن البوابة لن تعمل. يمكنك بسهولة حلها باستخدام {domNode && ReactDOM.createPortal(stuff, domNode)} أو ما شابه. نظرًا لأنه كان عليك بالفعل إجراء نوع من الفحص لتحديد ما إذا كان يمكنك الحصول على عقدة DOM - لذلك في هذه المرحلة ، يجب أن يكون لديك بيانات كافية لاختيار عدم إرسال البوابة الإلكترونية.

أرغب في إصلاح هذا باعتباره "مشكلتي الأولى الجيدة"

+1

هل يمكنني العمل على هذه القضية؟

بالتأكيد. أعتقد أنك تستطيع. إذن إلى أي مدى ذهبت؟ أنا أفكر في التقاطها أيضًا.

  • 2

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

مرحبًا هنا طلب السحب الجزئي لهذه المشكلة
https://github.com/facebook/react/pull/15473

أي شخص لا يزال على هذا؟ أنا أحب أن آخذه.

ما هي حالة هذا؟ كيف يمكنني إعادة إنتاجه؟

لا تزال هذه القضية؟

لم أحصل على رد بشأن هذه المسألة أيضا.

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

هل يمكنني تناول هذه المسألة؟

مرحبا ، هل هناك من يعمل على هذه القضية؟ إذا لم أكن أود أن آخذه.

إذا لم يعمل أحد على ذلك ، يمكنني ذلك

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

يجب أن تعمل إضافة عنصر div بشكل جيد

`class Para توسع React.Component {
يجعل() {
إرجاع (

بعض النصوص
)

}
} `

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