简体   繁体   English

当组件重新渲染时,React SVG 消失

[英]React SVG disappearing when component rerenders

I am making a react application with some SVG icons within my components.我正在我的组件中使用一些 SVG 图标制作一个 React 应用程序。 For instance, I have a SearchBar component which includes the input element along with a button that has a Search Icon in it.例如,我有一个 SearchBar 组件,它包含输入元素以及一个带有搜索图标的按钮。

I am using inline SVG for all my SVG icons, by setting the xlinkHref attribute accordingly from a single sprite file.通过从单个精灵文件相应地设置 xlinkHref 属性,我为所有 SVG 图标使用内联 SVG。

Everything seems to work just fine, except that my SVG icons randomly disappear when I click on them.一切似乎都很好,除了当我点击它们时我的 SVG 图标随机消失。 The button element that contains the icon does not disappear, just the SVG icon.包含图标的按钮元素不会消失,只是 SVG 图标。 I checked the DOM tree on the devtools, and it seems like that there is an issue with a node called "#shadow-root".我检查了 devtools 上的 DOM 树,似乎名为“#shadow-root”的节点存在问题。

When my SVG icons are visible, they are placed as child nodes of the "#shadow-root".当我的 SVG 图标可见时,它们被放置为“#shadow-root”的子节点。 However, when they disappear, the DOM tree shows that "#shadow-root" node no longer has any child node, effectively making my SVG icons nowhere to be found.然而,当它们消失时,DOM 树显示“#shadow-root”节点不再有任何子节点,有效地使我的 SVG 图标无处可寻。

Before disappearing:消失前: 在此处输入图片说明

After disappearing:消失后: 在此处输入图片说明

It is heart-breaking to see my lovely SVG icons suddenly disappear...看到我可爱的 ​​SVG 图标突然消失了,真是令人心碎……

Please advise!请指教!

-----EDIT----- Here is the code for the component that I am using to insert SVG icons: -----编辑----- 这是我用来插入 SVG 图标的组件的代码:

import React from "react";

const Icon = ({ name }) => (
  <svg>
    <use xlinkHref={`img/icons/sprite.svg#icon-${name}`} />
  </svg>
);
export default Icon;

you can try another ways to include your SVG.您可以尝试其他方式来包含您的 SVG。 I mentione three possibilities:我提到了三种可能性:

  1. Use the .svg file as an img src, as we can see in create-react-app:使用 .svg 文件作为 img src,我们可以在 create-react-app 中看到:
    import logo from './logo.svg';

    render() {...
          <img src={logo} className="App-logo" alt="logo" />
          ...}
  1. Use svg-inline-react.使用 svg-inline-react。 For more info check here :有关更多信息,请查看此处
    import InlineSVG from 'svg-inline-react';

    const svgSource = `<svg xmlns="......</svg>`;
    <InlineSVG src={svgSource} />
  1. Convert the SVG into base64 and set it in the background image of your button.将 SVG 转换为 base64 并将其设置在按钮的背景图像中。

Good luck.祝你好运。

You can build the SVG element yourself.您可以自己构建 SVG 元素。 You can let React build the empty <svg> element, then manually insert a <use> element using a ref and an effect:您可以让 React 构建空的<svg>元素,然后使用 ref 和效果手动插入一个<use>元素:

const Icon = React.memo(({ url }) => {
  const [svgNode, setSvgNode] = React.useState(null);

  React.useLayoutEffect(() => {
    if (svgNode === null) {
      return;
    }

    const useNode = document.createElementNS("http://www.w3.org/2000/svg", "use");
    useNode.setAttributeNS("http://www.w3.org/1999/xlink", "href", url);
    svgNode.appendChild(useNode);

    return () => {
      useNode.remove();
    };
  }, [type, svgNode]);

  return <svg ref={setSvgNode} />;
});

Based on this implementation .基于这个实现

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM