Home > other >  How can I render a SVG based on ternary operator inside a JSX?
How can I render a SVG based on ternary operator inside a JSX?

Time:01-18

I am using Stencil.js, but the syntax is similar to React.

const iconSVG = <svg>...</svg>

return (
      <button>
      {this.icon ?
       this.position === 'left'
        ? iconSVG `${this.label}`
        : `${this.label} icon` 
      : this.label}
      </button>
    );

This gives me an error: iconSVG is not a function

return (
      <button>
      {this.icon ?
       this.position === 'left'
        ? <svg> ...</svg> `${this.label}`
        : `${this.label} icon` 
      : this.label}
      </button>
    );

This doesn't work because of the this.label. There can only be one element (value).

 return (
          <button>
          {this.icon ?
           this.position === 'left'
            ? `${<svg> ...</svg>} `${this.label}`
            : `${this.label} icon` 
          : this.label}
          </button>
        );

This gives me [Object object] inside the Button next to the label.

const iconSVG = () => <svg> ...</svg>

return (
      <button>
      {this.icon ?
       this.position === 'left'
        ? iconSVG() `${this.label}`
        : `${this.label} icon` 
      : this.label}
      </button>
    );

This gives me an error: iconSVG(...) is not a function obviously because the JSX is read first.

So, how do I do it? How can I render the SVG inside the JSX?

CodePudding user response:

You can try :

return (
    <button>
        {this.icon && this.position === 'left' && <svg>...</svg>}
        {this.label}
        {this.icon && this.position !== 'left' && ' icon'}
    </button>
);

CodePudding user response:

Use your svg as following.

export const IconSvg = () => {
  return (
      <svg>
        ...
      </svg>
  );
};

And then , used with your ternary operator.

eg.

import React from "react";

const isRed = true;

export const RedIconSvg = () => {
  return (
      <svg width="100" height="100">
        <circle cx="50" cy="50" r="40" fill="red" />
      </svg>
  );
};

export const BlueIconSvg = () => {
  return (
      <svg width="100" height="100">
        <circle cx="50" cy="50" r="40" fill="blue" />
      </svg>
  );
};

function App() {
  return (
    <div className="App">
      {isRed ? <RedIconSvg/> : <BlueIconSvg/>}
    </div>
  );
}

export default App;

CodePudding user response:

Because you are specifying more than one item inside an expression, you need to use an array:

#1

render() {
    const iconSVG = <svg></svg>;
    return (
        <button>
            {this.icon ?
                this.position === 'left'
                    ? [iconSVG, this.label]
                    : `${this.label} icon`
                : this.label}
        </button>
    );
}

#2

render() {
    return (
        <button>
            {this.icon
                ? this.position === 'left'
                    ? [<svg> ...</svg>, this.label]
                    : `${this.label} icon`
                : this.label}
        </button>
    );
}

#3 would be the same as #2.

#4

render() {
    const iconSVG = () => <svg> ...</svg>;

    return (
        <button>
            {this.icon
                ? this.position === 'left'
                    ? [iconSVG(), this.label]
                    : `${this.label} icon`
                : this.label
            }
        </button>
    );
}
  • Related