'Create dynamic svg icons component in ReactJs

I want to create a React component for my SVG icons but if I use this component several times (with different props) in another component, it always renders the same icon.

My icon.js component:

import { ReactComponent as ArrowDown} from '../assets/icons/icons-line-arrrow-down.svg';
import { ReactComponent as ArrowUp} from '../assets/icons/icons-line-arrrow-up.svg';

const iconTypes = {
  arrowDown: ArrowDown,
  arrowUp: ArrowUp,
}

const IconComponent = ({name, ...props}) => {
  let Icon = iconTypes[name];
  return <Icon {...props} />;

};

export default IconComponent

The usage:

import Icon from 'components/Icon';

It works:

class MyComponent extends React.PureComponent {
  render() {
    return (
      <div>
        <Icon name={"arrowDown"}/>
      </div>
    )}
}

It works too:

class MyComponent extends React.PureComponent {
  render() {
    return (
      <div>
        <Icon name={"arrowUp"}/>
      </div>
    )}
}

It renders ArrowDown icon twice:

class MyComponent extends React.PureComponent {
  render() {
    return (
      <div>
        <Icon name={"arrowDown"}/>
        <Icon name={"arrowUp"}/>
      </div>
    )}
}

So there is my question: why only the first SVG icon is rendered several times when I use my component twice and how to fix it?



Solution 1:[1]

Your code works well, I've created the code snippet from it:

CodeSandbox (JavaScript)

CodeSandbox (TypeScript)

index.js

import React from "react";
import ReactDOM from "react-dom";
import Icon from "./icon";

function App() {
  return (
    <div>
      <Icon name="arrowUp" />
      <Icon name="arrowDown" />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

icon.js

import React from "react";
import { ReactComponent as ArrowDown } from "./arrow-down.svg";
import { ReactComponent as ArrowUp } from "./arrow-up.svg";

const iconTypes = {
  arrowDown: ArrowDown,
  arrowUp: ArrowUp
};

const IconComponent = ({ name, ...props }) => {
  let Icon = iconTypes[name];
  return <Icon {...props} />;
};

export default IconComponent;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1