ChatGPT解决这个技术问题 Extra ChatGPT

SVG use tag and ReactJS

So normally to include most of my SVG icons that require simple styling, I do:

<svg>
    <use xlink:href="/svg/svg-sprite#my-icon" />
</svg>

Now I have been playing with ReactJS as of late evaluating it as a possible component in my new front-end development stack however I noticed that in its list of supported tags/attributes, neither use or xlink:href are supported.

Is it possible to use svg sprites and load them in this way in ReactJS?

For future visitors, you can now use <use xlinkHref="/svg/svg-sprite#my-icon" />.
xlink:href is deprecated, now supposed to just use href -- developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
@MattGreer As of 2018, Safari still needs xlink:href so we still need to use it. Actual web applications need to either use the common denominator of browser features, or implement specific workarounds / polyfills.
I'm just adding this comment to help others who search for this error, which was solved by Jon Surrell's answer below: Property 'xlink' does not exist on type 'SVGProps<SVGImageElement>
Hey, maybe accept a different answer? Community seems to be agreed about that. Just a helpful suggestion, thanks.

J
Jon Surrell

MDN says that xlink:href is deprecated in favor of href. You should be able to use the href attribute directly. The example below includes both versions.

As of React 0.14, xlink:href is available via React as the property xlinkHref. It is mentioned as one of the "notable enhancements" in the release notes for 0.14.

<!-- REACT JSX: -->
<svg>
  <use xlinkHref='/svg/svg-sprite#my-icon' />
</svg>

<!-- RENDERS AS: -->
<svg>
  <use xlink:href="/svg/svg-sprite#my-icon"></use>
</svg>

Update 2018-06-09: Added info about href vs xlink:href attributes and updated example to include both. Thanks @devuxer

Update 3: At time of writing, React master SVG properties can be found here.

Update 2: It appears that all svg attributes should now be available via react (see merged svg attribute PR).

Update 1: You may want to keep an eye on the svg related issue on GitHub for additional SVG support landing. There are developments in the works.

Demo:

const svgReactElement = ( { /* Deprecated xlink:href usage */ } ); var resultHtml = ReactDOMServer.renderToStaticMarkup(svgReactElement); document.getElementById('render-result-html').innerHTML = escapeHtml(resultHtml); ReactDOM.render(svgReactElement, document.getElementById('render-result') ); function escapeHtml(unsafe) { return unsafe.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); }

Render result of rendering:

<svg
  viewBox="0 0 1340 667"
  width="100"
  height="100"
>
  <image width="667" height="667" href="https://i.imgur.com/w7GCRPb.png"/>
  { /* Deprecated xlink:href usage */ }
  <image width="667" height="667" x="673" xlinkHref="https://i.imgur.com/w7GCRPb.png"/>
</svg>

ReactDOMServer.renderToStaticMarkup() output:


ReactDOM.render() output:


> Update 25 Dec 2015: It appears that all svg attributes should now be available via react (see merged svg attribute PR). Is there a standard way to use these svg attributes? Will they all be camel cased like in the case of xlink:href => xlinkHref ?
@majorBummer take a look here
this really needs to be the correct answer, especially when the current chosen answer recommends dangerouslySetInnerHTML, which is, well, dangerous
According to MDN (developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href), xlink:href has been deprecated, and the recommendation is to use href without the namespace prefix. (Note, however, if you're using TypeScript, the typings haven't yet been updated to reflect this.)
At the time of writing, xlink:href is supported in Safari, but href is not.
D
David Hellsing

Update september 2018: this solution is deprecated, read Jon’s answer instead.

--

React doesn’t support all SVG tags as you say, there is a list of supported tags here. They are working on wider support, f.ex in this ticket.

A common workaround is to inject HTML instead for non-supported tags, f.ex:

render: function() {
    var useTag = '<use xlink:href="/svg/svg-sprite#my-icon" />';
    return <svg dangerouslySetInnerHTML={{__html: useTag }} />;
}

No, don't use dangerouslySetInnerHTML. You can use xlinkHref as mentioned below.
Author should probably should remove this as the accepted answer
H
HoldOffHunger

If you encounter xlink:href, then you can get the equivalent in ReactJS by removing the colon and camelcasing the added text: xlinkHref.

You'll probably eventually be using other namespace-tags in SVG, like xml:space, etc.. The same rule applies to them (i.e., xml:space becomes xmlSpace).


m
mwiegboldt

As already said in Jon Surrell's answer, use-tags are supported now. If you are not using JSX, you can implement it like this:

React.DOM.svg( { className: 'my-svg' },
    React.createElement( 'use', { xlinkHref: '/svg/svg-sprite#my-icon' }, '' )
)

A
Ahrengot

I created a little helper that works around this issue: https://www.npmjs.com/package/react-svg-use

first npm i react-svg-use -S then simply

import Icon from 'react-svg-use'

React.createClass({
  render() {
    return (
      <Icon id='car' color='#D71421' />
    )
  }
})

and this will then generate the following markup

<svg>
  <use xlink:href="#car" style="fill:#D71421;"></use>
</svg>

Dude, you must be commended with +500 points for this!
e
emir

I had problems with showing SVG in Gutenberg block, by referencing it with xlink:href. We used xlinkHref property in react, but after compiling, instead to render as xlink:href it was rendered to xlinkhref, and SVG was not displayed. After a lot of examining, I found out that xlink:href is deprecated (although it worked if we add it in html, or directly in chrome dev tools), and that href should be used instead. So after changing it to href it worked.

"SVG 2 removed the need for the xlink namespace, so instead of xlink:href you should use href." https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href

This is the code I used

SVG file

<svg id="svg-source" style="display: none;" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
    <symbol id="svg-arrow-accordion" viewBox="0 0 15 24" fill="none">
        <path id="Path_1662" data-name="Path 1662" d="M15.642,14.142h-3V1.5H0v-3H15.642Z" transform="translate(2 2) rotate(45)" fill="currentColor"></path>
    </symbol>
</svg>

React file

<svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" width="15" height="24">
<use href="#svg-arrow-accordion"></use>
</svg>