2017-06-03 1 views
1

Ich habe eine SVG-Map-Komponente, die ich immer aktualisieren will, wenn sich die Requisiten ändern. Hinzufügen und Subtrahieren von Klassen auf einigen Pfaden ... so etwas.Snap.svg in Reagieren - wie auf die Svg in einer Lebenszyklus-Methode zugreifen?

Snap.svg schien der richtige Weg zu sein. Wenn jemand einen besseren Weg kennt, würde ich es gerne hören!

hier ist also meine Render-Methode, und die beiden Linien markiert mit Stirnrunzeln sind die, die ich möchte in einem Lifecycle-Methode zu erhalten arbeiten wie ComponentWillReceiveProps

render() { 
    var map = Snap('#map'); 
    Snap.load("images/map.svg", function(data){ 
     if (map) { 
      map.append(data); 
      const a2047 = map.select('#a2047');    <---- :(
      a2047.attr({stroke:'yellow', strokeWidth:'6px'}) <---- :(
     } 
    }) 

    return (
     <div className="map" id="map"/> 
    ); 
} 

Das Problem ist, wird map nirgendwo anders arbeiten außer in diesem Snap.load Rückruf. Ich habe mehrere Möglichkeiten ausprobiert, state, window.map, this.map ... zu verwenden, und ich bekomme Fehler wie 'wählen ist keine Funktion'.

Wie bekomme ich Zugriff auf die Karte in ComponentWillReceiveProps?

Oder ist Snap.svg sogar der Weg für diese Anwendung zu gehen?

+0

Hat diese - dank - aber Snap.load eine neue Map mit jedem Wechsel in Requisiten. Suchen Sie nach der besten Lösung ... – dwilbank

+0

Setzen Sie vielleicht eine 'geladene' Flagge im Status? – dwilbank

Antwort

4

Sie tun eine direkte DOM-Manipulation mit Snap.svg und weder render noch componentWillReceiveProps ist ein guter Ort, um das zu tun. Ich empfehle Ihnen, das in componentDidUpdate zu tun, das sofort nach der Wiedergabe der Komponente aufruft. Dies wird jedoch nicht für das anfängliche Rendern aufgerufen. Also müssen wir diese DOM-Manipulation sowohl in componentDidUpdate als auch in componentDidMount machen. Um zu verhindern, dass derselbe Code wiederholt wird, können Sie diese Operation in einer anderen allgemeinen Klassenmethode beibehalten und sie unter componentDidUpdate und componentDidMount aufrufen. Da Ihre Requisiten an dieser Stelle aktualisiert wurden, können Sie sie einfach unter der Adresse this.props innerhalb der neuen Klassenmethode aufrufen.

Beispiel:

// @sigfried added to answer his comment below 
import Snap from 'snapsvg-cjs'; 

export default class Mermaid extends Component { 
    svgRender() { 
    let element = Snap(this.svgDiv) 
    Snap.load("images/map.svg", function(data){ 
     if (element) { 
     element.append(data); 
     } 
    }); 
    } 
    componentDidMount() { 
    this.svgRender(); 
    } 
    componentDidUpdate() { 
    this.svgRender(); 
    } 
    render() { 
    return <div ref={d=>this.svgDiv=d} /> 
    } 
} 
+0

Danke, Sir, dass ich meine Struktur verbessert habe. Es funktioniert alles jetzt. Das ursprüngliche Problem - wie man Zugriff auf die vorhandene Karte bekommt, wurde gelöst mit this.map = map – dwilbank

+0

@dwilbank Ich bin froh, dass es dir geholfen hat –

+0

Sorry, um dicht zu sein, könnte aber einer von euch (@dwilbank oder @tharaka -wijebandara) post, wie die Lösung aussieht? Der Teil, der mir am wenigsten klar ist, ist der Render-Return. Soll es leer sein? (Dann entferne vielleicht das auskommentierte Zeug in der ursprünglichen Frage.) Soll Snap es wirklich mit seiner ID finden? Wäre kein Ref besser? – Sigfried

Verwandte Themen