Est-il acceptable d'utiliser React.render () plusieurs fois dans le DOM?


107

Je souhaite utiliser React pour ajouter des composants plusieurs fois dans le DOM. Ce violon montre ce que je cherche à faire, et il ne jette aucune erreur. Voici le code:

HTML:

<div id="container">
    <!-- This element's contents will be replaced with the first component. -->
</div>

<div id="second-container">
    <!-- This element's contents will be replaced with the second component. -->
</div>

JS:

var Hello = React.createClass({
    render: function() {
        return <div>Hello {this.props.name}</div>;
    }
});

React.render(<Hello name="World" />, document.getElementById('container'));

React.render(<Hello name="Second World" />, document.getElementById('second-container'));

J'ai vu cette question et je crains qu'en faisant ce qui précède, je risque que les composants React interfèrent les uns avec les autres. La réponse à cette question suggère d'utiliser le rendu côté serveur, ce qui n'est pas une option pour moi car j'utilise Django côté serveur.

D'un autre côté, peut-être que ce que je fais est OK parce que je n'ai qu'une seule instance de la bibliothèque React montée (par opposition à plusieurs composants appelant leur propre instance de React)?

Cette façon d'utiliser plusieurs instances DOM est-elle une bonne façon d'utiliser React?

Réponses:


120

Oui, il est parfaitement normal d'appeler React.renderplusieurs fois sur la même page. Comme vous l'avez suggéré, la bibliothèque React elle-même n'est chargée qu'une seule fois, mais chaque appel à React.rendercréera une nouvelle instance de composant indépendante des autres. (En fait, une telle situation n'est pas rare sur les sites en cours de transition vers React, où certaines parties de la page sont générées à l'aide React.renderet d'autres non.)


9
génial - il est également extrêmement utile pour "suralimenter" une application Django existante. Je souhaite utiliser Django pour le contenu rendu afin d'obtenir le référencement et utiliser React pour l'interaction de l'utilisateur avec les éléments DOM. Cela le rend super simple à réaliser.
YPCrumble

vous pouvez probablement aussi regarder shouldComponentUpdate et il pourrait démarrer les performances à l'avenir (probablement pas dans votre cas). Voici la référence: facebook.github.io/react/docs/component-specs.html
Jim

@YPCrumble si la réponse des hoppers est correcte, veuillez la marquer
Dana Woodman

Et qu'en est-il du cas où il y a plusieurs ReactDOM.render()qui doivent insérer des composants dans le même en divfonction de la page que vous ouvrez? En particulier, vous n'avez qu'un seul élément concaténé uglifié app.jsque vous <script src="app.js">dans chaque page. Et cela charge les bibliothèques, par exemple, jQuery, Bootstrap, React et a votre code JS personnalisé et vos composants React. Si vous visitez /foo, vous avez ReactDOM.render(<Foo />, getElemById('content')). Si vous visitez /bar', you have ReactDOM.render (<Bar />, getElemById ('content')) `. Ils interfèrent. Comment gérez-vous cela?
Vert

3
@Green Je ne suis pas sûr de comprendre, si les composants sont sur des pages séparées, comment pourraient-ils interférer? Sinon, pourquoi ne pas ajouter un nouvel élément conteneur pour chaque composant, c'est-à-dire:ReactDOM.render(<Foo/>, document.getElementById('content').appendChild(document.createElement('div')))
trémie

3

Cette approche est correcte du point de vue des performances de chargement de page, mais il existe d'autres inconvénients et plusieurs racines React doivent être évitées si possible.

  • Différentes racines React ne peuvent pas partager de contexte, et si vous avez besoin de communiquer entre les racines React, vous devrez vous replier sur les événements DOM globaux
  • Vous bénéficiez moins des optimisations des performances telles que le découpage du temps - suspense et rendu asynchrone. Il n'est pas possible de suspendre au-delà des limites racine de React

Plus de raeding - https://github.com/facebook/react/issues/12700

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.