使用React渲染SVG时避免重复的过滤器定义

时间:2019-10-14 13:22:09

标签: reactjs react-hooks svg-filters

我正在使用React渲染一些包含过滤器的SVG元素。这是一个简化的示例:

function ShadowCircle() {
  return (
    <g>
      <defs>
        <filter id="dropShadow" x="-20%" y="-20%" width="200%" height="200%">
          <feOffset result="offOut" in="SourceAlpha" dx="1" dy="1" />
          <feGaussianBlur result="blurOut" in="offOut" stdDeviation="1" />
          <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
        </filter>
      </defs>
      <circle r="4" cx="50" cy="50" fill="blue" filter="url(#dropShadow)" />
    </g>
  );
}

function App() {
  return <svg width="100" height="100">
    <ShadowCircle />
  </svg>
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

只要我仅呈现<ShadowCircle />的单个实例,此方法就可以正常工作,否则我将在DOM中得到重复的过滤器(和重复的ID)。

理想情况下,我希望能够:

  • 确保每次渲染一个或多个阴影圆时仅渲染一个滤镜
  • 在不使用过滤器时将其删除

我尝试了使用createPortaluseEffect挂钩的自定义方法,但是遇到了两个问题:

  • 如果不将SVG元素包装在<svg>标签中,则无法呈现它们,因此门户网站必须是<div>,并且我所有的过滤器最终都保存在单独的<svg>文档中。 / li>
  • getElementById内调用useEffect来检查该过滤器是否已经在页面上被证明是不可靠的,尤其是当多个元素同时呈现到页面上时。

如何在需要时渲染一个滤镜(由一个或多个组件组成),然后再将其删除?

0 个答案:

没有答案