首页 文章

如何修改导入的第三方反应组件的tagName?

提问于
浏览
0

我正在使用 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必须是一个非常常见的用例 . 如果没有,只是添加aria标签,使用语义元素名称,等等..

如何更改无法控制的反应组件的tagName?

1 回答

  • 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>
       )
    }
    

相关问题