Итерация и рендеринг SVG в цикле

Я довольно долго делал итерационную карту с реакцией и добился большого успеха. Единственное, с чем я не сталкивался, - это рендеринг SVG с итерацией.

Начнем с того, что компонент React настроит итерацию mp и импортирует массив данных из ./data.js.

Cards.js

import React from 'react';
import data from './data';

const icons = data.map(icon => (
  <>
   <div><span>{icon.svg}</span> {icon.type}</div>
  </>
));

const Cards = () => (<>{ icons }</>);

export default Cards;

Массив данных ...

data.js

export default[
 {
   svg: './icons/menu.svg',
   type: Menu
 },
{
   svg: './icons/home.svg',
   type: Home
 },
 {
   svg: './icons/clock.svg',
   type: History
 }
]

Проблема в том, что он не может отобразить .svg в следующем каталоге, но вместо этого отображает строку ./icons/xxx.svg.

Я пробовал другой способ ..

svg: require('./icons/clock.svg'),

... по-прежнему получаю тот же результат. У меня заканчиваются идеи. Какие-либо предложения? Я понимаю, что require('') работал с тегом JSX img ... Но я использую только файлы .svg, есть ли способ импортировать файлы svg в массив данных?

Вы пробовали это <div> <span> {require (icon.svg)} </span> {icon.type} </div>

Hemadri Dasari 12.10.2018 19:52
Поведение ключевого слова "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) для оценки ваших знаний,...
1
1
2 546
4

Ответы 4

Попробуйте настроить его так:

import menu from './icons/menu.svg';
import home from './icons/home.svg';
import clock from './icons/clock.svg';

export default[
 {
   svg: menu,
   type: 'Menu'
 },
{
   svg: home,
   type: 'Home'
 },
 {
   svg: clock,
   type: 'History'
 }
]

И реализуем это так:

<div>
  <span>
    <img src = {icon.svg} />
  </span> 
  {icon.type}
</div>

@Ted, предположим, если у вас будет 100 файлов SVG?

Madpop 22.05.2019 18:34

Храните свои данные такими, какие они есть, и используйте require для их рендеринга

<div>
  <span>
    {require(icon.svg)}
  </span> 
  {icon.type}
</div>

Спасибо, ребята, что нашли время, чтобы помочь ... Этот метод действительно работает, дал мне идею, и я это отмечаю. Но это было не совсем то, что я искал, поскольку для этого пришлось бы использовать теги <img>, которые не позволили бы мне регулировать размер, цвет и т. д. Я хочу избежать перехода между редактором кода и программами иллюстрации. К счастью, я нашел альтернативное решение, оно может быть утомительным, но оно работает. Вот что я сделал ...

Начнем с создания компонента React PropTypes ..

Icon.js

import React from 'react';
import PropTypes from 'prop-types';

const config = {
  svg: {
    display: 'flex-inline',
    margin: '0 auto'
  }
};

const Icons = props => (
  <svg
    style = {config.svg}
    width = {`${props.size}`}
    height = {`${props.size}`}
    viewBox = {`0 0 512 512`}
    className = {props.className}
  >
    <path d = {props.icon} />
  </svg>
);

Icons.propTypes = {
  icon: PropTypes.string.isRequired,
  size: PropTypes.number.isRequired,
  color: PropTypes.string,
  className: PropTypes.string.isRequired
};

Icons.defaultProps = {
  size: 32
};

Создайте другой файл и включите массив путей SVG с определенным именем например. меню, дом, часы

icons.js

export const SVGicon = {
  menu: /*Insert your SVG path here starting with 'M...*/, 

  home: /*Insert your SVG  path here starting with 'M...*/,

  clock: /*Insert your SVG path here starting with 'M...*/,

}

Вернемся к data.js и немного изменим (Спасибо, Тед!)

data.js

import { SVGicon } from './icons'

export default[
  {
    svg: SVGicon.menu,
    type: 'Henu'
  },
  {
    svg: SVGicon.home,
    type: 'Home'
  },
  {
    svg: SVGicon.clock,
    type: 'History'
  }
]

Вернемся, чтобы отреагировать на компоненты и немного изменить ...

Cards.js

import React from 'react';
import data from './data';
import Icon from './Icon'; /* PropType Component */

const icons = data.map(icon => (
 <React.Fragment>
  <Icons icon = {icon.svg} className = "svg-icon" size = {12} />
 </React.Fragment>
));

const Cards = () => (<React.Fragment>{ icons }</React.Fragment>);

export default Cards;

и css после className = "svg-icon" для настройки цвета, эффекта и т. д.

main.scss

.svg-icon{
  fill: rgba(blue, .5);
  transition: fill .3s ease-out;
  &:hover{
    fill: rgba(red, 1);
 }

Это должно показать массив различных значков SVG с возможностью управления цветом, размером и т. д. Надеюсь на эту помощь

Я пытаюсь загрузить около 50 SVG из общей папки, и можете ли вы сказать мне, как лучше всего следовать? @sirrius

Madpop 22.05.2019 18:33

Вы можете уточнить? Я не уверен, что понимаю, что вы имеете в виду под «SVG из общей папки»?

sirrus 22.05.2019 18:51

скажем, у меня есть 50 файлов svg в папке, например a.svg, 2.svg, 3.svg ..... и я хочу отобразить эти svg в таблице

Madpop 22.05.2019 18:56

пожалуйста, проверьте эту проблему stackoverflow.com/questions/56260773/…

Madpop 22.05.2019 18:57

Я так понимаю, вы хотите реализовать 50 .svg из общей папки без индивидуальной настройки? Если это так, посмотрите ответ Теда выше. Создайте папку с именем icons или как угодно назовите ее. Поместите все 50 .svg в папку ... Импортируйте все svg и настройте массивы. Это, наверное, самый удобный и лучший подход.

sirrus 22.05.2019 20:33

@sirrus Спасибо за ответ. Что делать, если у иконки SVG не единственный путь, как сохранить его в данных?

turok87 04.10.2020 11:28

@sirrus Но что, если у SVG другое окно просмотра. Как я могу перебирать такие SVG

tkamath99 26.11.2020 15:48

Я бы добавил это как комментарий к @sirrius, но репутации маловато :)

Я последовал предложенному решению, но мои значки не были видны. Это связано с тем, что порт просмотра по-прежнему принимает статические значения вместо значений динамического размера для ширины и высоты.

Так что вместо:

const Icons = props => (
  <svg
    style = {config.svg}
    width = {`${props.size}`}
    height = {`${props.size}`}
    viewBox = {`0 0 512 512`}
    className = {props.className}
  >
    <path d = {props.icon} />
  </svg>
);

в котором значки будут иметь высоту и ширину viewBox 512 независимо от размера (представьте, что у него есть svg размером 32 внутри 512 viewBox, он может оказаться вне поля зрения, потому что размеры не пропорциональны).

У тебя должно быть:

const Icons = props => (
  <svg
    style = {config.svg}
    width = {`${props.size}`}
    height = {`${props.size}`}
    viewBox = {`0 0 ${props.size} ${props.size}`}
    className = {props.className}
  >
    <path d = {props.icon} />
  </svg>
);

Это регулирует viewBox в соответствии с предоставленным размером.

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