簡體   English   中英

如何在 React 中導入 SVG 圖標

[英]How to Import SVG icons in React

我想在應用程序中導入太多 SVG 圖標,並且每個圖標都需要通過 css 自定義顏色,這是最簡單的導入方式? 導入到<img/>標簽將不支持通過 css 填充更改顏色。 為每個圖標創建一個 .js 組件對於 250 多個圖標來說太難了。 另一個選擇是什么? 請幫忙

import IconArrow from "./Arrow.svg";
import Circlearrowdownright from "./Arrow.js";

<img className="ico" src={IconArrow} />
<i className="ico"><Circlearrowdownright /></i>

https://codesandbox.io/s/svg-icon-3z0qu6

您可以直接將其導入並用作 React 組件:

import { ReactComponent as ExampleIcon} from './icons/ExampleIcon.svg';

<ExampleIcon className="css-class"/>

您可以動態導入 SVG 並即時渲染 ( CodeSandbox )。 無需為每個 SVG 文件創建單獨的.js組件。

hook

function useDynamicSVGImport(name, options = {}) {
  const ImportedIconRef = useRef();
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState();

  const { onCompleted, onError } = options;
  useEffect(() => {
    setLoading(true);
    const importIcon = async () => {
      try {
        ImportedIconRef.current = (
          await import(`./${name}.svg`)
        ).ReactComponent;
        if (onCompleted) {
          onCompleted(name, ImportedIconRef.current);
        }
      } catch (err) {
        if (onError) {
          onError(err);
        }
        setError(err);
      } finally {
        setLoading(false);
      }
    };
    importIcon();
  }, [name, onCompleted, onError]);

  return { error, loading, SvgIcon: ImportedIconRef.current };
}

使用鈎子的Icon組件

/**
 * Simple wrapper for dynamic SVG import hook. You can implement your own wrapper,
 * or even use the hook directly in your components.
 */
export const Icon = ({ name, onCompleted, onError, ...rest }) => {
  const { error, loading, SvgIcon } = useDynamicSVGImport(name, {
    onCompleted,
    onError
  });
  if (error) {
    return error.message;
  }
  if (loading) {
    return "Loading...";
  }
  if (SvgIcon) {
    return <SvgIcon {...rest} />;
  }
  return null;
};

用法

return (
    <>
      <Icon
        name="Arrow"
        fill="gray"
        width="100"
        onCompleted={handleOnCompleted}
        onError={handleIconError}
      />
      <Icon
        name="delete"
        fill="gray"
        width="50"
        onCompleted={handleOnCompleted}
        onError={handleIconError}
      />
    </>
  );

React 與原生 Web 組件配合良好。 只有當您想使用事件與它們交互或傳遞數據時,React(仍然)無法支持標准: https://custom-elements-everywhere.com/

  • 創建一個<svg-icon>標簽只需要幾行代碼。
  • 添加了一個replaceWith屬性,以便您加載的<svg>替換<svg-icon> ,使使用全局 CSS 更容易。
  • 添加了shadowRoot屬性以任何內容移動到 shadowDOM

 customElements.define("svg-icon", class extends HTMLElement { async connectedCallback( src = this.getAttribute("src"), shadowRoot = this.shadowRoot || this.attachShadow({mode:"open"}) ) { shadowRoot.innerHTML = await (await fetch(src)).text() shadowRoot.append(...this.querySelectorAll("[shadowRoot]")) this.hasAttribute("replaceWith") && this.replaceWith(...shadowRoot.childNodes) } });
 body { display: grid; grid: 1fr/1fr 5fr; } path { stroke: green; stroke-width: .2; fill: red; }
 <svg-icon replaceWith src="https://svg-cdn.github.io/bi-arrows.svg"></svg-icon> <svg-icon src="https://svg-cdn.github.io/simple-worldmap.svg"> <style shadowRoot> path { fill: orange } </style> </svg-icon>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM