web-dev-qa-db-fra.com

Comment utiliser ReactDOM.createPortal () dans React 16?

J'utilise React 16 et ai besoin de portails, mais je ne parviens pas à trouver de documentation sur cette fonctionnalité. Quelqu'un sait-il comment l'utiliser pour le moment?

https://github.com/facebook/react/pull/10675

Merci pour tout conseil.

23
Slbox

React v16 vient de publier il y a quelques heures (Yay !!) qui supporte officiellement Portal .

Qu'est-ce que Portal? Depuis combien de temps existe-t-il?

Les portails offrent un moyen de première classe pour rendre les enfants dans un nœud DOM qui existe en dehors de la hiérarchie DOM du composant parent.

Portal n'est pas un nouveau concept dans la communauté de réaction. Il existe de nombreuses bibliothèques prenant en charge ce type de fonctionnalité. par exemple react-portal et react-gateway .

Que se passe-t-il lors du rendu d'une application de réaction?

Généralement, lors du rendu d'une application React, un seul élément DOM est utilisé pour restituer l'intégralité de l'arborescence React.

class HelloReact extends React.Component {
   render() {
       return (
          <h1>Hello React</h1>
       );
   }
}

ReactDOM.render(<HelloReact />, document.getElementById('root'));

Comme vous pouvez le constater, nous transformons notre composant react en un élément DOM ayant id root.

Qu'est-ce que Portal et pourquoi est-il nécessaire? Pourquoi est-ce là?

Les portails sont un moyen de rendre React enfants en dehors de la hiérarchie DOM principale du composant parent sans perdre le contexte de réaction. J'insiste là-dessus car des bibliothèques très populaires comme react-router , redux utilisent énormément le contexte react. La disponibilité du contexte lorsque vous utilisez Portal est donc très utile.

Selon les réagir docs,

Un cas d'utilisation typique des portails est lorsqu'un composant parent a un dépassement de capacité: style caché ou style z-index, mais que vous ayez besoin que l'enfant se "décompose" visuellement de son conteneur. Par exemple, les boîtes de dialogue, les cartes survolées et les info-bulles.

Ainsi, avec les portails, vous pouvez rendre un arbre de réaction parallèle sur un autre nœud DOM si nécessaire. Même s'il est rendu dans le nœud DOM différent, le composant parent peut intercepter les événements non capturés. Voir ceci codepen fourni dans la documentation elle-même.

L'exemple ci-dessous devrait vous donner plus d'idée:

// index.html
<html>
    <body>
        <div id="root"></div>
        <div id="another-root"></div>
    </body>
</html>

// index.jsx
const mainContainer = document.getElementById('root');
const portalContainer = document.getElementById('another-root');

class HelloFromPortal extends React.Component {
    render() {
         return (
           <h1>I am rendered through a Portal.</h1>
         );
    }
}

class HelloReact extends React.Component {
    render() {
        return (
             <div>
                 <h1>Hello World</h1>
                 { ReactDOM.createPortal(<HelloFromPortal />, portalContainer) }
             </div>
        );
    }
}

ReactDOM.render(<HelloReact />, mainContainer);

https://codesandbox.io/s/62rvxkonnw

Vous pouvez utiliser devtools inspect element et voir que <h1>I am rendered through a Portal.</h1> est rendu à l'intérieur de #another-root tag, alors que <h1>Hello World</h1> est rendu à l'intérieur de #root tag.

J'espère que cela t'aides :)

Mise à jour : Pour répondre à commentaire de PhillipMunin .

Quelle est la différence entre ReactDOM.render et ReactDOM.createPortal?

  1. Même si le composant rendu via le portail est rendu ailleurs (en dehors de la racine du conteneur actuel), il reste présent en tant qu'enfant du même composant parent. (Qui a invoqué le ReactDOM.createPortal) Ainsi, tous les événements sur l’enfant sont propagés au parent. (Ofc, cela ne fonctionne pas si vous arrêtez manuellement la propagation de l'événement.)

  2. Le même contexte est accessible à l'intérieur du composant rendu via un portail. Mais pas dans le cas où nous faisons ReactDOM.render directement.

J'ai créé une autre démo pour illustrer mon propos. https://codesandbox.io/s/42x771ykwx

36
Hardik Modha

Les portails sont créés en appelant la méthode createPortal à l'intérieur de la méthode render de votre composant.

render() {
  return (
    <div>
      {ReactDOM.createPortal(this.renderPortal(), this.props.portalEl)}
    </div>
  )
}

renderPortal devrait renvoyer le contenu à restituer à l'intérieur du portail, tandis que portalEl est un élément DOM externe qui recevra le contenu.

Une personne a récemment indiqué que des informations sur les portails se trouvaient dans tests de réaction .

0
Marko