Snap.svg in React - how to access the svg in a lifecycle method?

扶醉桌前 提交于 2019-12-22 17:42:32

问题


I have an svg map component which I want to update whenever the props change. Adding and subtract classes on some of the paths... that sort of thing.

Snap.svg seemed to be the way to go. If someone knows a better way I'd like to hear it!

So here's my render method, and the two lines marked with frowns are the ones I want to get working in a lifecycle method such as 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"/>
    );
}

The problem is, map won't work anywhere else except inside this Snap.load callback. I tried several ways, using state, window.map, this.map... and I get errors such as 'select is not a function'.

How to get access to the map in ComponentWillReceiveProps ?

Or is Snap.svg even the way to go for this application?


回答1:


You are doing a direct DOM manipulation with Snap.svg and neither render nor componentWillReceiveProps is a good place to do that. I recommend you to do that in componentDidUpdate which calls immediately after component gets rendered. But this will not be invoked for the initial render. So we have to do this DOM manipulation in both componentDidUpdate and componentDidMount. To prevent repeating the same code, you can keep this operation in another common class method and call it from both componentDidUpdate and componentDidMount. Also, since your props have been updated at this point you can simply access them with this.props inside the new class method.

Example:

// @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} />
  }
}


来源:https://stackoverflow.com/questions/44340278/snap-svg-in-react-how-to-access-the-svg-in-a-lifecycle-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!