Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use SVG filter attribute in React.js

I have been researching a bit on data representation with SVG and React and they seem a perfect fit. However SVG is not yet supported in React, and an addon does not exist yet https://github.com/facebook/react/issues/2250.

Yet there is some workarounds like using dangerouslySetInnerHTML for some elements, in my case I cannot find one yet.

I want to use filter attribute inside a circle svg element. However It gets not rendered into the DOM. Here it is my React Component:

class DeviceDot extends React.Component {
  render () {
    const { app, idx } = this.props

    return  <circle cx={50 * idx} cy={50 * idx} r='25' filter={`url(#${app})`} fill='mediumorchid' />
  }
}

And the filter:

class FilterSVG extends React.Component {
  render () {
    const { app, idx } = this.props
    const icon = app ? `/api/apps/${app}/logo` : '/img/dflt.png'

    return (
      <filter id={app || 'default'} x='0%' y='0%' width='100%' height='100%'>
        <feImage xlinkHref={icon} />
      </filter>
    )
  }
}

However I cannot use dangerouslySetInnerHTML without wrapping this component, which I want to reuse as is (a circle SVG element). Is there any work around to use this attribute (and others) you are using right now?

Thank you.

like image 545
jsdario Avatar asked Oct 18 '22 14:10

jsdario


2 Answers

For filter you can use CSS styles as workaround, like this:

const style = {
  filter: `url(#${app || 'default'})`
}

And the returning component...

return <circle cx={50 * idx} cy={50 * idx} r='25' style={style} />

If you only want to filter you can use plain CSS. Thus, add it to React props.

like image 67
pablo.pi Avatar answered Oct 21 '22 05:10

pablo.pi


React does support SVG. The issue you've linked to has been fixed. In some cases the JSX attribute will be different to the HTML attribute, e.g. xlinkHref instead of xlink:href. It should not be necessary to use dangerouslySetInnerHTML.

In the code above, it looks as if you're simply using the wrong variable. You want this instead:

filter={`url(#${icon})`}
like image 28
David L. Walsh Avatar answered Oct 21 '22 06:10

David L. Walsh