React: Unerwartete Warnung beim Hydratisieren mit Portal und SSR

Erstellt am 15. Apr. 2018  ·  24Kommentare  ·  Quelle: facebook/react

Möchten Sie eine Funktion anfordern oder einen Fehler melden?

Fehler

Wie ist das aktuelle Verhalten?

Angesichts des folgenden (vereinfachten) Ausschnitts:

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>
    )
  }
} 

Wenn div#root ein gültiges div , wird der folgende Fehler angezeigt, wenn nach SSR hydratisiert wird:

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

Die Warnung verschwindet, wenn ich die Definition von HoverMenu auf Folgendes aktualisiere:

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)
  }
}

Ich würde es vorziehen, dies nicht zu tun, da durch setState in componentDidMount doppeltes Rendering verursacht wird.

Ich verstehe nicht ganz, was mir dieser Fehler sagt. In beiden Fällen wird kein <div /> serverseitig gerendert. Der Fehler ist besonders verwirrend, da das HoverMenu DOM div nicht einmal in einem DOM span gerendert wird. (Ich frage mich, ob dies passiert, weil HoverMenu in einem React span verschachtelt ist.)

Was ist das erwartete Verhalten?

Es wird kein Fehler ausgegeben. Oder zumindest, dass die Fehlermeldung klarer ist.

Welche Versionen von React und welcher Browser / welches Betriebssystem sind von diesem Problem betroffen?

Chrome 65
Reaktion 16.2
(SSR bis Next 5.1)

medium Bug good first issue

Hilfreichster Kommentar

Obwohl feuchtigkeitsspendende Portale nicht unterstützt werden (https://github.com/facebook/react/issues/13097), macht die Nachricht selbst keinen Sinn. Wir müssen das untersuchen und beheben.

Alle 24 Kommentare

Ich habe ein ähnliches Problem, das auch durch erneutes Rendern auf dem Client über setState behoben werden kann.
In meinem Fall versuche ich, ein Modal in einem Portal zu rendern. Der Modal Komponente kehrt null , wenn auf dem Server gerendert und erstellt ein Portal auf dem Client. Das DOM wird jedoch nach der Flüssigkeitszufuhr durcheinander gebracht.

ZB wenn ich es so in meiner Hauptkomponente benutze:

<Modal>
This is a test
</Modal>

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

Anstatt dies nach der Flüssigkeitszufuhr zu bekommen:

<!-- 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>

Ich verstehe das:

<!-- 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>

Und die Warnung ist dieselbe ( Expected server HTML to contain a matching <div> in <div> ). Ich verwende React 16.3 mit einer benutzerdefinierten SSR-Methode.

Ich bin mir nicht sicher, ob dies das beabsichtigte Verhalten ist.

Obwohl feuchtigkeitsspendende Portale nicht unterstützt werden (https://github.com/facebook/react/issues/13097), macht die Nachricht selbst keinen Sinn. Wir müssen das untersuchen und beheben.

@gaearon Der Zweck der Korrektur ist

  • [] Erkennt, dass Portal in hydrate () verwendet wird, und gibt dann eine korrektere Fehlermeldung nach Invariante aus.
    zB invariant violation: Portal is not support on SSR. For more detail, please refer https://github.com/facebook/react/issues/13097
  • [] Test hinzufügen

    • [] Wenn das Portal mit dem Hydrat () verwendet wird, sollte die obige Fehlermeldung ausgegeben werden

Recht?
Ich bin bereit, wenn es nicht dringend ist.

Ich plane den Entwurf eines SSR-Dokuments für das Website-Repo, daher muss ich mit dem Hydratationsmechanismus vertraut sein.
Ich denke, diese Untersuchung wird für meinen Plan hilfreich sein.
https://github.com/facebook/react/pull/13379

Warum werden Portale auf SSR nicht unterstützt, auch wenn "nichts" gerendert wird?

Es scheint nicht so, als wäre nichts am besten zu rendern - ich sehe nicht, was Portalinhalte anders macht, als wir es nicht als Server-Rendering wert betrachten.

Wir werden wahrscheinlich zusammen mit der Überarbeitung des Server-Renderers auf Spannung zurückkommen.

Portale sind konzeptionell reine Client-Komponenten. für Dinge wie modals verwendet , dass man in der Regel nicht auf dem Server machen möchte - sie nehmen auch ein DOM - Element, das renderToString nicht , weil es kein dom ist. Ich sehe nicht, wie etwas Sinnvolles mit ihnen auf dem Server zu tun ist - ich sehe nur auch nichts Wertvolles beim Werfen.

verwendet für Dinge wie Modalitäten

Das ist ein Anwendungsfall, aber es gibt auch andere wie Seitenleisten und ähnliches, die nicht unbedingt nur für Kunden bestimmt sind.

Sie nehmen auch ein Dom-Element

Richtig - im aktuellen Design. Es könnte sich ändern. https://github.com/facebook/react/pull/8386#issuecomment -262375265

Ich sehe auch nichts Wertvolles vom Werfen.

Der Wert des Werfens besteht darin, ausdrücklich anzuerkennen, dass das Portal nicht funktioniert. Sie können es leicht mit {domNode && ReactDOM.createPortal(stuff, domNode)} oder ähnlichem umgehen. Da Sie bereits eine Art Überprüfung durchführen mussten, um festzustellen, ob Sie den DOM-Knoten erhalten können, sollten Sie zu diesem Zeitpunkt über genügend Daten verfügen, um das Portal nicht zu senden.

Ich möchte dies als mein "gutes erstes Problem" beheben.

+1

Kann ich an diesem Problem arbeiten?

Sicher. Ich denke du kannst. Wie weit bist du gegangen? Ich denke tatsächlich daran, es auch aufzuheben.

  • 2

Hallo Leute, jede Idee, wie ich die Datei finden kann, in der das Problem liegt, kann ich bekommen, bitte etwas Hilfe.

Hey, hier ist die teilweise Pull-Anfrage für dieses Problem
https://github.com/facebook/react/pull/15473

Ist noch jemand dabei? Ich würde es gerne annehmen.

Wie ist der Status davon? Wie könnte ich es reproduzieren?

Ist das noch ein Problem?

Ich habe auch zu diesem Thema keine Antwort erhalten.

Ich glaube, der Status dieses Themas ist noch offen.

Kann ich dieses Problem angehen?

Hallo, arbeitet jemand an diesem Problem? Wenn nicht, würde ich es gerne nehmen.

Wenn niemand daran arbeitet, kann ich

Ist das noch ein Problem? Es scheint, als ob versucht wurde, das Problem zu beheben, aber das zugrunde liegende Problem ist, dass einige Leute tatsächlich möchten, dass Portale beim serverseitigen Rendern funktionieren. Wenn dies der Fall ist, kann dieses Problem geschlossen werden?

Das Hinzufügen eines div-Elements sollte einwandfrei funktionieren

`class Para erweitert React.Component {
render () {
Rückkehr (

Etwas Text
)

}}
} `

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen