【问题标题】:hiding react svg component with linearGradient in Header also hides the svg outside of Header在 Header 中隐藏带有 linearGradient 的 react svg 组件也将 svg 隐藏在 Header 之外
【发布时间】:2021-06-20 18:41:15
【问题描述】:

我有一个带有 linearGradient 的 svg react 组件,我在我的 Header 组件和我的主要组件中呈现。当我将 display: none 样式设置为 Header 组件时,我希望 Header 组件中的 svg 是隐藏的,而主组件中的 svg 是可见的。当我在没有linearGradient的情况下使用svg时,我得到了隐藏在Header中并在主组件中可见的svg的预期行为。但是,如果svg使用linearGradient,那么将display: none设置为Header会隐藏Header和主组件中的svg。

为了重现该问题,我有 2 个反应组件 PythonIcon(使用线性渐变)和 WebpackIcon(不使用线性渐变)。在我的 App.js 中,我渲染了 Header 并在我的主要组件中同时渲染了 PythonIconWebpackIcon

import React from "react";
import Header from "./Header";
import PythonIcon from "./PythonIcon";
import WebpackIcon from "./WebpackIcon";

function App() {
  return (
    <div>
      <Header />
      <main style={{ marginTop: "1rem", border: "1px solid green" }}>
        <h1>
          <PythonIcon width="20" height="20" />
          Python
        </h1>
        <h1>
          <WebpackIcon width="20" height="20" />
          Webpack
        </h1>
      </main>
    </div>
  );
}

export default App;

在我的 Header 组件中,我还渲染了 PythonIconWebpackIcon

import React from "react";
import PythonIcon from "./PythonIcon";
import WebpackIcon from "./WebpackIcon";

export default function Header() {
  return (
    <header style={{ border: "1px solid red", display: "block" }}>
      <h1>
        <PythonIcon width="20" height="20" />
        Python
      </h1>
      <h1>
        <WebpackIcon width="20" height="20" />
        Webpack
      </h1>
    </header>
  );
}

页面看起来像这样:

但是一旦我在 Header 组件中将 display: block 更改为 display: none,页面看起来像这样:

请注意,webpack 图标(不使用 linearGradient)正确显示在主组件中,但 python 图标(使用 linearGradient)没有。

这是出乎意料的。难道我做错了什么?有没有办法隐藏标题中的python图标而不隐藏主要组件中的python图标?我正在尝试使用 css media-query 创建一个响应式导航栏来显示/隐藏导航栏。不幸的是,隐藏带有 svg 图标的导航栏也会在我渲染的其他组件中隐藏 svg 图标。

我在https://github.com/kimbaudi/react-svg-lineargradient-issue提供了一个最小的复制品

【问题讨论】:

  • 我想我知道为什么会遇到这个问题。这可能是因为在 svg 中使用 linearGradient 需要 id,因此使用 linearGradient 渲染多个 svg 将渲染具有相同 id 的多个元素。我需要看看是否将唯一 id 作为道具传递给带有 linearGradient 的 svgs 解决了这个问题。
  • 不要显示:无。尝试 svg 元素的宽度和高度 0。您可以添加 position:absolute 并将其扔出窗口left

标签: reactjs svg


【解决方案1】:

所以我找到了解决这个问题的方法。发生这种情况的原因是因为使用 linearGradient 或 RadialGradient 的 svg 包含 ids,当您在一个页面中渲染多个 svg 时,它会导致奇怪的事情发生,因为 DOM 期望有一个唯一的 id。

所以我之前的PythonIcon react svg 组件硬编码了ids,看起来像这样:

import React from "react";

const PythonIcon = (props) => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 64 64"
    width="64"
    height="64"
    {...props}
  >
    <linearGradient
      id="pythonLinearGradient1"
      x1="611.11"
      x2="720.13"
      y1="-280.51"
      y2="-374.3"
      gradientTransform="matrix(.32049 0 0 -.32362 -197.36 -88.951)"
      gradientUnits="userSpaceOnUse"
    >
      <stop stopColor="#5A9FD4" offset="0" />
      <stop stopColor="#306998" offset="1" />
    </linearGradient>
    <path
      fill="url(#pythonLinearGradient1)"
      strokeWidth=".56976"
      d="m31.344 0c-2.6209 0-5.1278 0.2279-7.2929 0.62674-6.4383 1.1395-7.6348 3.5325-7.6348 7.9197v5.8116h15.27v1.9372h-21.024c-4.4441 0-8.3185 2.6779-9.572 7.7488-1.4244 5.8116-1.4814 9.458 0 15.498 1.0825 4.5011 3.7034 7.7488 8.1476 7.7488h5.2418v-6.9511c0-5.0139 4.3872-9.515 9.572-9.515h15.27c4.2732 0 7.6348-3.4755 7.6348-7.7488v-14.529c0-4.1593-3.4755-7.236-7.6348-7.9197-2.6209-0.45581-5.3558-0.62674-7.9767-0.62674zm-8.2615 4.672c1.5953 0 2.8488 1.3104 2.8488 2.9058 0 1.5953-1.3104 2.9058-2.8488 2.9058-1.5953 0-2.8488-1.3104-2.8488-2.9058 0-1.5953 1.2535-2.9058 2.8488-2.9058z"
    />
    <linearGradient
      id="pythonLinearGradient2"
      x1="762.27"
      x2="723.34"
      y1="-431.07"
      y2="-375.99"
      gradientTransform="matrix(.32049 0 0 -.32362 -197.36 -88.951)"
      gradientUnits="userSpaceOnUse"
    >
      <stop stopColor="#FFD43B" offset="0" />
      <stop stopColor="#FFE873" offset="1" />
    </linearGradient>
    <path
      fill="url(#pythonLinearGradient2)"
      strokeWidth=".56976"
      d="m48.836 16.352v6.7802c0 5.2418-4.4441 9.6859-9.572 9.6859h-15.213c-4.1593 0-7.6348 3.5895-7.6348 7.7488v14.529c0 4.1593 3.5895 6.5523 7.6348 7.7488 4.843 1.4244 9.458 1.6523 15.27 0 3.8744-1.1395 7.6348-3.3616 7.6348-7.7488v-5.8116h-15.27v-1.9372h22.904c4.4441 0 6.0964-3.0767 7.6348-7.7488 1.5953-4.786 1.5384-9.4011 0-15.498-1.0825-4.4441-3.1907-7.7488-7.6348-7.7488zm-8.5464 36.807c1.5953 0 2.8488 1.3104 2.8488 2.9058 0 1.5953-1.3104 2.9058-2.8488 2.9058-1.5953 0-2.8488-1.3105-2.8488-2.9058-0.05698-1.5953 1.2535-2.9058 2.8488-2.9058z"
    />
  </svg>
);

export default PythonIcon;

现在我将一个随机字符串(我只是使用Math.random() 用于演示目的)附加到ids,并且当我隐藏标题时,我不再遇到 Python 图标在主体上消失的问题。这是更新后的PythonIcon 组件:

import React from "react";

const PythonIcon = (props) => {
  const rand1 = Math.random()
  const rand2 = Math.random()
  return (
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 64 64"
      width="64"
      height="64"
      {...props}
    >
      <linearGradient
        id={`pythonLinearGradient1-${rand1}`}
        x1="611.11"
        x2="720.13"
        y1="-280.51"
        y2="-374.3"
        gradientTransform="matrix(.32049 0 0 -.32362 -197.36 -88.951)"
        gradientUnits="userSpaceOnUse"
      >
        <stop stopColor="#5A9FD4" offset="0" />
        <stop stopColor="#306998" offset="1" />
      </linearGradient>
      <path
        fill={`url(#pythonLinearGradient1-${rand1})`}
        strokeWidth=".56976"
        d="m31.344 0c-2.6209 0-5.1278 0.2279-7.2929 0.62674-6.4383 1.1395-7.6348 3.5325-7.6348 7.9197v5.8116h15.27v1.9372h-21.024c-4.4441 0-8.3185 2.6779-9.572 7.7488-1.4244 5.8116-1.4814 9.458 0 15.498 1.0825 4.5011 3.7034 7.7488 8.1476 7.7488h5.2418v-6.9511c0-5.0139 4.3872-9.515 9.572-9.515h15.27c4.2732 0 7.6348-3.4755 7.6348-7.7488v-14.529c0-4.1593-3.4755-7.236-7.6348-7.9197-2.6209-0.45581-5.3558-0.62674-7.9767-0.62674zm-8.2615 4.672c1.5953 0 2.8488 1.3104 2.8488 2.9058 0 1.5953-1.3104 2.9058-2.8488 2.9058-1.5953 0-2.8488-1.3104-2.8488-2.9058 0-1.5953 1.2535-2.9058 2.8488-2.9058z"
      />
      <linearGradient
        id={`pythonLinearGradient2-${rand2}`}
        x1="762.27"
        x2="723.34"
        y1="-431.07"
        y2="-375.99"
        gradientTransform="matrix(.32049 0 0 -.32362 -197.36 -88.951)"
        gradientUnits="userSpaceOnUse"
      >
        <stop stopColor="#FFD43B" offset="0" />
        <stop stopColor="#FFE873" offset="1" />
      </linearGradient>
      <path
        fill={`url(#pythonLinearGradient2-${rand2})`}
        strokeWidth=".56976"
        d="m48.836 16.352v6.7802c0 5.2418-4.4441 9.6859-9.572 9.6859h-15.213c-4.1593 0-7.6348 3.5895-7.6348 7.7488v14.529c0 4.1593 3.5895 6.5523 7.6348 7.7488 4.843 1.4244 9.458 1.6523 15.27 0 3.8744-1.1395 7.6348-3.3616 7.6348-7.7488v-5.8116h-15.27v-1.9372h22.904c4.4441 0 6.0964-3.0767 7.6348-7.7488 1.5953-4.786 1.5384-9.4011 0-15.498-1.0825-4.4441-3.1907-7.7488-7.6348-7.7488zm-8.5464 36.807c1.5953 0 2.8488 1.3104 2.8488 2.9058 0 1.5953-1.3104 2.9058-2.8488 2.9058-1.5953 0-2.8488-1.3105-2.8488-2.9058-0.05698-1.5953 1.2535-2.9058 2.8488-2.9058z"
      />
    </svg>
  );
};

export default PythonIcon;

这是显示当使用display: none隐藏标题时 Python 图标未隐藏的预期行为的屏幕截图

【讨论】:

    猜你喜欢
    • 2020-02-11
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    相关资源
    最近更新 更多