React: Avertissement inattendu lors de l'hydratation avec portail et SSR

Créé le 15 avr. 2018  ·  24Commentaires  ·  Source: facebook/react

Voulez-vous demander une fonctionnalité ou signaler un bogue ?

punaise

Quel est le comportement actuel?

Compte tenu de l'extrait de code (simplifié) suivant:

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 est un div valide qui existe, l'erreur suivante s'affiche lors de l'hydratation après SSR:

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

L'avertissement disparaît si je mets à jour la définition de HoverMenu en:

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

Je préférerais ne pas le faire à cause du double rendu causé par setState dans componentDidMount .

Je ne comprends pas très bien ce que me dit cette erreur. Non <div /> est rendu côté serveur dans les deux cas. L'erreur est particulièrement déroutante, car le HoverMenu DOM div n'est même pas rendu dans un DOM span . (Je me demande si cela se produit car HoverMenu est imbriqué dans un React span .)

Quel est le comportement attendu?

Aucune erreur n'est générée. Ou du moins que le message d'erreur est plus clair.

Quelles versions de React et quel navigateur / système d'exploitation sont concernés par ce problème?

Chrome 65
Réagir 16.2
(SSR à Next 5.1)

medium Bug good first issue

Commentaire le plus utile

Bien que les portails d'hydratation ne soient pas pris en charge (https://github.com/facebook/react/issues/13097), le message lui-même n'a pas de sens. Nous devrons enquêter et résoudre ce problème.

Tous les 24 commentaires

J'ai un problème similaire, qui peut également être résolu en effectuant un nouveau rendu sur le client via setState.
Dans mon cas, j'essaye de rendre un modal à l'intérieur d'un portail. Le composant Modal renvoie null lorsqu'il est rendu sur le serveur et crée un portail sur le client. Cependant, le DOM est gâché après l'hydratation.

Par exemple, si je l'utilise comme ça dans mon composant principal:

<Modal>
This is a test
</Modal>

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

Au lieu de l'obtenir après l'hydratation:

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

J'ai compris:

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

Et l'avertissement est le même ( Expected server HTML to contain a matching <div> in <div> ). J'utilise React 16.3 avec une méthode SSR personnalisée.

Je ne sais pas si c'est le comportement prévu.

Bien que les portails d'hydratation ne soient pas pris en charge (https://github.com/facebook/react/issues/13097), le message lui-même n'a pas de sens. Nous devrons enquêter et résoudre ce problème.

@gaearon Le but de la correction est

  • [] Détecte que Portal est utilisé dans hydrate (), puis lance plus correctement un message d'erreur par invariant.
    par exemple invariant violation: Portal is not support on SSR. For more detail, please refer https://github.com/facebook/react/issues/13097
  • [] Ajouter un test

    • [] Si le portail est utilisé avec l'hydrate (), devrait lancer le message d'erreur ci-dessus

droite?
Je suis prêt si ce n'est pas urgent.

Je prévois une ébauche de document SSR vers un dépôt de site Web, je dois donc être familier avec le mécanisme d'hydratation.
Je pense que cette enquête sera utile pour mon plan.
https://github.com/facebook/react/pull/13379

Pourquoi les portails ne sont-ils pas pris en charge sur SSR, même pour rendre "rien"?

Il ne semble pas que rien ne soit le meilleur - je ne vois pas ce qui rend le contenu du portail différent que nous ne considérons pas utile de rendre le serveur.

Nous y reviendrons probablement avec la refonte du moteur de rendu du serveur pour le suspense.

Les portails sont conceptuellement des composants uniquement client; utilisé pour des choses comme modaux que l' on en général ne voudrait pas rendre sur le serveur - ils prennent aussi un élément dom, qui ne renderToString parce qu'il n'y a pas dom. Je ne vois pas comment il y a quelque chose de significatif à faire avec eux sur le serveur - je ne vois tout simplement rien de valable à lancer.

utilisé pour des choses comme les modaux

C'est un cas d'utilisation, mais il y en a aussi d'autres comme les barres latérales et similaires qui ne sont pas nécessairement réservés au client.

ils prennent aussi un élément dom

À droite - dans la conception actuelle. Cela pourrait changer. https://github.com/facebook/react/pull/8386#issuecomment -262375265

Je ne vois pas non plus quelque chose de précieux à lancer.

L'intérêt de lancer est de reconnaître explicitement que le portail ne fonctionnera pas. Vous pouvez facilement le contourner avec {domNode && ReactDOM.createPortal(stuff, domNode)} ou similaire. Parce que vous avez déjà dû faire une sorte de vérification pour déterminer si vous pouvez obtenir le nœud DOM - donc à ce stade, vous devriez avoir suffisamment de données pour choisir de ne pas émettre le portail.

Je souhaite résoudre ce problème en tant que "bon premier problème"

+1

Puis-je travailler sur ce problème?

Sûr. Je suppose que tu peux. Alors, jusqu'où êtes-vous allé? Je pense en fait à le ramasser aussi.

  • 2

Salut les gens, toute idée de comment je peux trouver le fichier où se trouve le problème, je peux l'obtenir, s'il vous plaît un peu d'aide.

Hey, voici la demande d'extraction partielle pour ce problème
https://github.com/facebook/react/pull/15473

Quelqu'un est-il encore là-dessus? J'adorerais me lancer.

Quel est le statut de cela? Comment pourrais-je le reproduire?

Est-ce toujours un problème?

Je n'ai pas non plus reçu de réponse à ce sujet.

Je crois que le statut de cette question est toujours ouvert.

Puis-je résoudre ce problème?

Bonjour, est-ce que quelqu'un travaille sur ce problème? Sinon, je voudrais le prendre.

si personne n'y travaille, je peux

Est-ce toujours un problème? Il semble que des tentatives aient été faites pour le résoudre, mais le problème sous-jacent est que certaines personnes veulent en fait que les portails fonctionnent sur le rendu côté serveur? Si tel est le cas, ce problème peut-il être résolu?

L'ajout d'un élément div devrait fonctionner correctement

`class Para étend React.Component {
render () {
revenir (

Du texte
)

}
} `

Cette page vous a été utile?
0 / 5 - 0 notes