React Import SVG встроенный из URL

Я работаю над проблемой, при которой изображение SVG необходимо загрузить с URL-адреса (AWS S3) в компонент реакции. Я могу успешно отображать и загружать изображение с помощью встроенного SVG-компонента реакции из локального файла. Однако файлы svg необходимо загружать прямо из корзины S3, импорт JS svg не работает с URL-адресами.

Итак, я пытаюсь найти лучшее альтернативное решение для этого?

Не уверен, что вы имеете в виду ... Если изображение видно в сети, вы должны иметь возможность добавить его в тег изображения, верно? Это как любой другой html-документ. Или это проблема при компиляции?

Jite 24.10.2018 11:07

Чтобы импортировать встроенный SVG как компонент React из URL-адреса, мне удалось загрузить SVG из локального встроенного файла, но не из URL-адреса.

Mikko Lasso 24.10.2018 11:16
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
2
9 231
3

Ответы 3

Вы должны получить изображение svg и вставить его в html

const SVG_URL = url = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/tiger.svg';

class Svg extends React.Component {
  state = {
    svg: null,
    loading: false,
  }

  componentDidMount() {
    fetch(this.props.url)
      .then(res => res.text())
      .then(text => this.setState({ svg: text }));
  }

  render() {
    const { loading, svg } = this.state;
    if (loading) {
      return <div className = "spinner"/>;
    } else if (!svg) {
      return <div className = "error"/>
    }
    return <div dangerouslySetInnerHTML = {{ __html: this.state.svg}}/>;
  }
}

ReactDOM.render(
  <Svg url='https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/tiger.svg' />,
  document.querySelector("#app")
);

Вы можете отредактировать пример здесь https://jsfiddle.net/anu6x3bk/

React не рекомендует использовать dangerouslySetInnerHTML, поэтому вам следует использовать какой-нибудь пакет, например svg-inline-react.

Нет необходимости во внешнем пакете, так как svg-inline-react также использует dangerouslySetInnerHTML: github.com/sairion/svg-inline-react/blob/master/src/index.js

Marko Šutija 20.08.2021 15:18

@ivnkld ответ указал мне правильное направление, спасибо! И для гуглеров, таких как я, вот реализация того же подхода с хуками:

import React, { useEffect, useState } from 'react';

const SvgInline = props => {
    const [svg, setSvg] = useState(null);
    const [isLoaded, setIsLoaded] = useState(false);
    const [isErrored, setIsErrored] = useState(false);

    useEffect(() => {
        fetch(props.url)
            .then(res => res.text())
            .then(setSvg)
            .catch(setIsErrored)
            .then(() => setIsLoaded(true))
    }, [props.url]);

    return (
        <div 
            className = {`svgInline svgInline--${isLoaded ? 'loaded' : 'loading'} ${isErrored ? 'svgInline--errored' : ''}`}
            dangerouslySetInnerHTML = {{ __html: svg }}
        />
    );
}

Для тех, кто не хочет использовать опасноSetInnerHTML, проверьте следующий пример. Как только мы получим svg как текст из api, мы будем использовать DOMParser для преобразования текста в объект Документ. Затем мы будем использовать React.createElement для рендеринга изображения (или) значка.

// utils/convertDocEleToReact.js
import { createElement } from "react";

const innerFunction = (element, props) => {
    const tagName = element.tagName;
    let _props = props || {};

    for(let i = 0; i < element.attributes.length; i++){
      _props[element.attributes[i].nodeName] = element.attributes[i].nodeValue;
    }

    let children = Array.from(element.children).map(item => innerFunction(item));

    return createElement(tagName, _props, children);
};

export const convertDocEleToReact = (element, props) => {
    try{
       return innerFunction(element, props);
    }
    catch(ex){
      return createElement("span", {}, "Error loading svg image");
    }
};
// components/SVGUrl.js
import React from "react";
import { convertDocEleToReact } from "./utils/convertDocEleToReact";

export const SVGUrl = ({ ...props }) => {
    const [ Comp, setComp ] = useState(null);
    const [loading, setLoading] = useState(false);

    useEffect(_ => {
        setLoading(true);
        fetch(/** svg url */)
          .then(res => res.text())
          .then(res => {
              const domParser = new DOMParser();
              const ele = domParser.parseFromString(res, "image/svg+xml");
              setComp(convertDocEleToReact(ele.documentElement, props));
              setLoading(false);
          });
    }, []);

    return loading ? "..." : Comp;
};

Другие вопросы по теме