React中的Snap.svg-如何在生命周期方法中访问svg? [英] Snap.svg in React - how to access the svg in a lifecycle method?

查看:177
本文介绍了React中的Snap.svg-如何在生命周期方法中访问svg?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个svg贴图组件,每当道具更改时,我都想对其进行更新. 在某些路径上添加和减去类……之类的东西.

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似乎是可行的方法.如果有人知道更好的方式,我想听听!

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

这是我的render方法,标有皱眉的两行是我想在生命周期方法(例如ComponentWillReceiveProps

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"/>
    );
}

问题是,map除了在此Snap.load回调内部之外,无法在其他任何地方工作.我尝试了几种方法,分别使用statewindow.mapthis.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'.

如何在ComponentWillReceiveProps中访问地图?

或者Snap.svg甚至是该应用程序的最佳选择?

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

推荐答案

您正在使用Snap.svg进行直接DOM操作,而rendercomponentWillReceiveProps都不是这样做的好地方.我建议您在 componentDidUpdate 中执行此操作组件渲染后立即生效.但这不会为初始渲染调用.因此,我们必须在componentDidUpdatecomponentDidMount中都进行此DOM操作.为避免重复相同的代码,您可以将此操作保留在另一个常见的类方法中,并从componentDidUpdatecomponentDidMount进行调用.另外,由于此时您的道具已经更新,因此您只需在新的类方法中使用this.props即可访问它们.

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.

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

这篇关于React中的Snap.svg-如何在生命周期方法中访问svg?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆