我正在使用babel-plugin-inline-react-svg
导入SVG并将其用作反应组件。问题是我需要将这些SVG嵌入到另一个SVG中。我想将根标记svg
转换为symbol
。当我按原样导入SVG时,结果是嵌套的SVG标记。这在技术上有效,但并非没有很多针对我的目标实现的怪癖(phantomjs)。我宁愿使用use xlink:href
,但我需要将第三方lib生成的根元素转换为标记名称符号
这是一些虚构的用法
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>
)
}
必须更改第三方库的根元素的tagName才是一个非常常见的用例。如果没有,只是添加咏叹调标签,使用语义元素名称等等。
如何更改无法控制的反应组件的tagName?
答案 0 :(得分:0)
I ended up using a Higher Order Component to intercept the ReactDOMElement coming from the 3rd party lib. I switched the type
of the element before it renders. Inspired heavily by 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>
)
}