第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何動態(tài)導(dǎo)入 SVG 并內(nèi)聯(lián)渲染

如何動態(tài)導(dǎo)入 SVG 并內(nèi)聯(lián)渲染

慕妹3146593 2022-07-08 18:10:30
我有一個接受一些參數(shù)并呈現(xiàn) SVG 的函數(shù)。我想根據(jù)傳遞給函數(shù)的名稱動態(tài)導(dǎo)入該 svg。它看起來像這樣:import React from 'react';export default async ({name, size = 16, color = '#000'}) => {  const Icon = await import(/* webpackMode: "eager" */ `./icons/${name}.svg`);  return <Icon width={size} height={size} fill={color} />;};根據(jù)動態(tài)導(dǎo)入的 webpack 文檔和神奇的評論“eager”:“不生成額外的塊。所有模塊都包含在當(dāng)前塊中,并且不會發(fā)出額外的網(wǎng)絡(luò)請求。仍然返回 Promise 但已經(jīng)解析。與靜態(tài)導(dǎo)入相比,模塊在調(diào)用導(dǎo)入之前不會執(zhí)行() 已制成?!边@就是我的圖標(biāo)解決的問題:> Moduledefault: "static/media/antenna.11b95602.svg"__esModule: trueSymbol(Symbol.toStringTag): "Module"試圖以我的函數(shù)試圖給我這個錯誤的方式呈現(xiàn)它:Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.我不明白如何使用這個導(dǎo)入的模塊將其渲染為組件,或者甚至可以這樣嗎?
查看完整描述

4 回答

?
慕慕森

TA貢獻1856條經(jīng)驗 獲得超17個贊

導(dǎo)入 SVG 文件時可以使用ref并命名導(dǎo)出。ReactComponent請注意,它必須是ref為了使它工作。


以下示例使用需要版本v16.8及更高版本的 React 鉤子。


示例動態(tài) SVG 導(dǎo)入鉤子:


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 };

}

打字稿中的示例動態(tài) SVG 導(dǎo)入鉤子:


interface UseDynamicSVGImportOptions {

  onCompleted?: (

    name: string,

    SvgIcon: React.FC<React.SVGProps<SVGSVGElement>> | undefined

  ) => void;

  onError?: (err: Error) => void;

}


function useDynamicSVGImport(

  name: string,

  options: UseDynamicSVGImportOptions = {}

) {

  const ImportedIconRef = useRef<React.FC<React.SVGProps<SVGSVGElement>>>();

  const [loading, setLoading] = useState(false);

  const [error, setError] = useState<Error>();


  const { onCompleted, onError } = options;

  useEffect(() => {

    setLoading(true);

    const importIcon = async (): Promise<void> => {

      try {

        ImportedIconRef.current = (

          await import(`./${name}.svg`)

        ).ReactComponent;

        onCompleted?.(name, ImportedIconRef.current);

      } catch (err) {

        onError?.(err);

        setError(err);

      } finally {

        setLoading(false);

      }

    };

    importIcon();

  }, [name, onCompleted, onError]);


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

}

對于那些在動態(tài)導(dǎo)入 SVG 時得到undefined的人來說ReactComponent,這是由于一個錯誤,即以某種方式將 SVG 添加ReactComponent到每個導(dǎo)入的 SVG 的 Webpack 插件不會在動態(tài)導(dǎo)入時觸發(fā)。


基于此解決方案,我們可以通過在您的動態(tài) SVG 導(dǎo)入中強制使用相同的加載器來臨時解決它。


唯一的區(qū)別是ReactComponent現(xiàn)在是default輸出。


ImportedIconRef.current = (await import(`!!@svgr/webpack?-svgo,+titleProp,+ref!./${name}.svg`)).default;

另請注意,使用帶有可變部分的動態(tài)導(dǎo)入時存在限制。這個 SO answer詳細解釋了這個問題。


要解決此問題,您可以使動態(tài)導(dǎo)入路徑更加明確。


例如,代替


// App.js

<Icon path="../../icons/icon.svg" />


// Icon.jsx

...

import(path);

...

您可以將其更改為


// App.js

<Icon name="icon" />


// Icon.jsx

...

import(`../../icons/${name}.svg`);

...


查看完整回答
反對 回復(fù) 2022-07-08
?
桃花長相依

TA貢獻1860條經(jīng)驗 獲得超8個贊

您的渲染函數(shù)(用于類組件)和函數(shù)組件不應(yīng)是異步的(因為它們必須返回 DOMNode 或 null - 在您的情況下,它們返回一個 Promise)。相反,您可以以常規(guī)方式渲染它們,然后導(dǎo)入圖標(biāo)并在下一次渲染中使用它。嘗試以下操作:


const Test = () => {

  let [icon, setIcon] = useState('');


  useEffect(async () => {

    let importedIcon = await import('your_path');

    setIcon(importedIcon.default);

  }, []);


  return <img alt='' src={ icon }/>;

};


查看完整回答
反對 回復(fù) 2022-07-08
?
紅顏莎娜

TA貢獻1842條經(jīng)驗 獲得超13個贊

我根據(jù)答案https://github.com/facebook/create-react-app/issues/5276#issuecomment-665628393進行了更改


export const Icon: FC<IconProps> = ({ name, ...rest }): JSX.Element | null => {

      const ImportedIconRef = useRef<FC<SVGProps<SVGSVGElement>> | any>();

      const [loading, setLoading] = React.useState(false);

      useEffect((): void => {

        setLoading(true);

        const importIcon = async (): Promise<void> => {

          try {

            // Changing this line works fine to me

            ImportedIconRef.current = (await import(`!!@svgr/webpack?-svgo,+titleProp,+ref!./${name}.svg`)).default;

          } catch (err) {

            throw err;

          } finally {

            setLoading(false);

          }

        };

        importIcon();

      }, [name]);


      if (!loading && ImportedIconRef.current) {

        const { current: ImportedIcon } = ImportedIconRef;

        return <ImportedIcon {...rest} />;

      }

      return null;

    };


查看完整回答
反對 回復(fù) 2022-07-08
?
LEATH

TA貢獻1936條經(jīng)驗 獲得超7個贊

動態(tài)加載 svg 的一種解決方案是使用require將其加載到img中,例如:

<img src={require(`../assets/${logoNameVariable}`)?.default} />


查看完整回答
反對 回復(fù) 2022-07-08
  • 4 回答
  • 0 關(guān)注
  • 389 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號