2017-04-22 51 views
0

我使用babel-plugin-inline-react-svg導入SVG並將它們用作反應組件。問題是我需要將這些SVG嵌入到另一個SVG中。我想將根標記svg轉換爲symbol。當我按原樣導入SVG時,嵌套SVG標籤的結果是什麼。技術上有效,但對我的目標實現(phantomjs)並非沒有許多怪癖。我寧願使用use xlink:href,但我需要通過第三方的lib生成的根元素轉換爲具有標籤的名稱符號如何修改導入的第三方反應組件的tagName?

下面是一些虛構的使用

import Flag from 'images/icons/flag.svg' 

export default() => { 
    return (
    <svg> 
     <Flag/> 
     <text>Foo</text> 
    </svg> 
    ) 
} 

這是什麼使是

<svg> 
    <svg> 
     <!-- contents of svg --> 
    </svg> 
    <text>Foo</text> 
</svg> 

我想什麼,能夠做的就是

import Flag from 'images/icons/flag.svg' 

export default() => { 
    return (
    <svg> 
     <defs> 
      <Flag as="symbol" id="flag"/> 
     </defs> 
     <use xlinkHref="#flag"/> 
     <text>Foo</text> 
    </svg> 
    ) 
} 

它萬畝t是必須更改第三方庫的根元素的tagName的一個非常常見的用例。如果沒有,但只是添加aria標籤,使用語義元素名稱,依此類推。

如何更改我無法控制的反應組件的tagName?

回答

0

我最終使用高階組件攔截來自第三方庫的ReactDOMElement。在渲染之前,我切換了元素的type。靈感來自https://github.com/pwmckenna/react-transform-style/blob/master/src/index.js

const TransformTag = (Component, tagName) => { 
    const ModifiedComponent = Component 
    const isFn = (typeof(Component) === 'function') 
    const render = isFn ? ModifiedComponent : ModifiedComponent.render 
    const modifiedRender = function() { 
    const { 
     props, 
     ...renderedRest 
    } = render.apply(this, arguments) 

    renderedRest.type = tagName // this is the magic 
    return { 
     props, 
     ...renderedRest 
    } 
    } 
    if (isFn) { 
    return modifiedRender 
    } else { 
    ModifiedComponent.prototype.render = modifiedRender 
    return ModifiedComponent 
    } 
} 

// usage 

export default SvgQuote =() => { 
    return (
     <svg> 
     <defs> 
      { TransformTag(Bill, 'symbol') } 
     </defs> 
     </svg> 
    ) 
}