Existe-t-il un moyen approprié d'intégrer d3.graphiques js dans L'application Facebook React?

Oui, je sais qu'il est de réagir art, mais , il semble être cassé.

Le problème est que d3.js consiste à muter le DOM du navigateur, et l'utiliser directement, par exemple dans la méthode componentDidMount, ne fonctionnera pas correctement, car toutes les modifications apportées au DOM du navigateur ne seront pas reflétées dans le DOM virtuel de React. Des idées?

25
demandé sur couchand 2014-02-20 13:32:02

3 réponses

Une stratégie pourrait être de construire un composant de boîte noire que vous ne laissez jamais React mettre à jour. La méthode du cycle de vie des composants shouldComponentUpdate() est destinée à permettre à un composant de déterminer lui-même si un réenroulement est nécessaire ou non. Si vousrenvoyez toujours false à partir de cette méthode, React ne plongera jamais dans les éléments enfants (c'est-à-dire, sauf si vous appelez forceUpdate()), donc cela agira comme une sorte de pare-feu contre le système de mise à jour profonde de React.

Utilisez le premier appel à render() pour conteneur pour le graphique, puis dessinez le graphique lui-même avec D3 dans la méthode componentDidMount(). Ensuite, il suffit de mettre à jour votre graphique en réponse aux mises à jour du composant React. Bien que vous ne puissiez pas supposé faire quelque chose comme ça dans shouldComponentUpdate(), Je ne vois aucune raison réelle de ne pas pouvoir appeler la mise à jour D3 à partir de là (voir le code du composant React _performUpdateIfNecessary()).

Donc votre composant ressemblerait à ceci:

React.createClass({
    render: function() {
        return <svg></svg>;
    },
    componentDidMount: function() {
        d3.select(this.getDOMNode())
            .call(chart(this.props));
    },
    shouldComponentUpdate: function(props) {
        d3.select(this.getDOMNode())
            .call(chart(props));
        return false;
    }
});

Notez que vous devez appelez votre graphique à la fois dans la méthode componentDidMount() (pour le premier rendu) ainsi que dans shouldComponentUpdate() (pour les mises à jour ultérieures). Notez également que vous avez besoin d'un moyen de transmettre les propriétés ou l'état du composant au graphique, et qu'ils sont spécifiques au contexte: dans le premier Rendu, ils ont déjà été définis sur this.props et this.state, mais dans les mises à jour ultérieures, les nouvelles propriétés ne sont pas encore définies sur le composant, vous devez donc utiliser

Voir le jsfiddle ici.

55
répondu couchand 2014-02-21 19:52:52

React peut également rendre directement les éléments SVG. Voici un exemple: Façons d'Intégrer Réagir.js et D3

5
répondu ahmad chatha 2014-11-17 19:45:25

Vous pouvez utiliser D3 comme utilitaire - c'est-à-dire ne pas utiliser D3 pour changer le DOM. Utilisez plutôt D3 pour ses échelles et ses axes, mais interpolez les sorties de ces fonctions D3 dans le html / svg.

Voici un exemple de mon projet.

 scale = d3.time.scale()
   .range([ 0, 100 ])
   .clamp(true)

...qui est passé via des accessoires à un composant...

React.DOM.rect({
          x: "#{props.scale(start)}%"
          width: "#{Math.abs( props.scale(end) - props.scale(start)) }%"
         })

Où React lie les données aux éléments, plutôt que les sélections de D3.

2
répondu adamwong246 2015-09-23 20:06:43