SVG ใช้แท็กและ ReactJS


114

โดยปกติแล้วในการรวมไอคอน SVG ส่วนใหญ่ของฉันที่ต้องใช้สไตล์เรียบง่ายฉันทำ

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

ตอนนี้ฉันได้เล่นกับ ReactJS แล้วเมื่อประเมินว่ามันเป็นองค์ประกอบที่เป็นไปได้ในกองพัฒนาส่วนหน้าใหม่ของฉัน แต่ฉันสังเกตเห็นว่าในรายการแท็ก / แอตทริบิวต์ที่รองรับไม่รองรับuseหรือไม่xlink:hrefได้รับการสนับสนุน

เป็นไปได้ไหมที่จะใช้สไปรต์ svg และโหลดด้วยวิธีนี้ใน ReactJS


28
สำหรับผู้เยี่ยมชมในอนาคตคุณสามารถใช้<use xlinkHref="/svg/svg-sprite#my-icon" />ไฟล์.
David Gilbertson

6
xlink:hrefเลิกใช้แล้วตอนนี้ควรจะใช้href- developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
Matt Greer

2
@MattGreer ในปี 2018 Safari ยังคงต้องการxlink:hrefดังนั้นเราจึงจำเป็นต้องใช้มัน เว็บแอปพลิเคชันจริงจำเป็นต้องใช้ตัวส่วนร่วมของคุณลักษณะเบราว์เซอร์หรือใช้วิธีแก้ปัญหาเฉพาะ / polyfills
Tobia

ฉันแค่เพิ่มความคิดเห็นนี้เพื่อช่วยผู้อื่นที่ค้นหาข้อผิดพลาดนี้ซึ่งแก้ไขได้โดยคำตอบของ Jon Surrell ด้านล่าง:Property 'xlink' does not exist on type 'SVGProps<SVGImageElement>
Joe M

คำตอบ:


50

อัปเดตกันยายน 2018 : โซลูชันนี้เลิกใช้แล้วโปรดอ่านคำตอบของ Jonแทน

-

ตอบสนองไม่สนับสนุน SVG แท็กทั้งหมดเป็นคุณจะพูดว่ามีรายชื่อของแท็กที่สนับสนุนที่นี่ พวกเขากำลังดำเนินการเกี่ยวกับการสนับสนุนที่กว้างขึ้น f.ex ในตั๋วนี้

วิธีแก้ปัญหาทั่วไปคือการฉีด HTML แทนสำหรับแท็กที่ไม่รองรับ f.ex:

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

19
ไม่ใช้dangerouslySetInnerHTML. คุณสามารถใช้xlinkHrefตามที่ระบุไว้ด้านล่าง
Tobia

ผู้เขียนควรจะลบสิ่งนี้ออกเนื่องจากเป็นคำตอบที่ยอมรับ
Aquasar

267

MDN บอกว่าxlink:href เลิกใช้แล้วในความโปรดปรานของhref. คุณควรจะใช้hrefแอตทริบิวต์ได้โดยตรง ตัวอย่างด้านล่างมีทั้งสองเวอร์ชัน

ในฐานะของReact 0.14 , สามารถใช้ได้ผ่านการตอบสนองเป็นสถานที่ให้บริการxlink:href xlinkHrefได้รับการกล่าวถึงว่าเป็นหนึ่งใน "การปรับปรุงที่โดดเด่น" ในบันทึกประจำรุ่นสำหรับ 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>

อัปเดต 2018-06-09:เพิ่มข้อมูลเกี่ยวhrefกับxlink:hrefแอตทริบิวต์vs และตัวอย่างที่อัปเดตเพื่อรวมทั้งสองอย่าง ขอบคุณ @devuxer

อัปเดต 3 : ในช่วงเวลาของการเขียน, การตอบสนองคุณสมบัติ SVG ต้นแบบสามารถพบได้ที่นี่

อัปเดต 2 : ดูเหมือนว่าแอตทริบิวต์ svg ทั้งหมดควรพร้อมใช้งานผ่าน react แล้ว (ดูแอตทริบิวต์ svg ที่ผสาน)

อัปเดต 1 : คุณอาจต้องการตรวจสอบปัญหาที่เกี่ยวข้องกับ svgใน GitHub สำหรับการเชื่อมโยงไปถึงการรองรับ SVG เพิ่มเติม มีการพัฒนาในผลงาน

การสาธิต:

const svgReactElement = (
  <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>
);

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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;"); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.1/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.1/umd/react-dom-server.browser.development.js"></script>

<h2>Render result of rendering:</h2>
<pre>&lt;svg
  viewBox=&quot;0 0 1340 667&quot;
  width=&quot;100&quot;
  height=&quot;100&quot;
&gt;
  &lt;image width=&quot;667&quot; height=&quot;667&quot; href=&quot;https://i.imgur.com/w7GCRPb.png&quot;/&gt;
  { /* Deprecated xlink:href usage */ }
  &lt;image width=&quot;667&quot; height=&quot;667&quot; x=&quot;673&quot; xlinkHref=&quot;https://i.imgur.com/w7GCRPb.png&quot;/&gt;
&lt;/svg&gt;</pre>

<h2><code>ReactDOMServer.renderToStaticMarkup()</code> output:</h2>
<pre id="render-result-html"></pre>
<h2><code>ReactDOM.render()</code> output:</h2>
<div id="render-result"></div>


2
> อัปเดต 25 ธันวาคม 2558: ดูเหมือนว่าตอนนี้แอตทริบิวต์ svg ทั้งหมดควรพร้อมใช้งานผ่าน react แล้ว (ดูแอตทริบิวต์ svg ที่ผสาน) มีวิธีมาตรฐานในการใช้คุณสมบัติ svg เหล่านี้หรือไม่? พวกเขาทั้งหมดจะถูกใส่ปลอกอูฐเหมือนในกรณีของ xlink: href => xlinkHref หรือไม่?
majorBummer

@majorBummer ดูที่นี่
Jon Surrell

2
นี่จะต้องเป็นคำตอบที่ถูกต้องจริงๆโดยเฉพาะอย่างยิ่งเมื่อคำตอบที่เลือกในปัจจุบันแนะนำว่าเป็นอันตราย
SetInnerHTML

1
ตามที่ MDN ( developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href ) xlink:hrefได้เลิกใช้แล้วและคำแนะนำคือให้ใช้hrefโดยไม่มีคำนำหน้าเนมสเปซ (อย่างไรก็ตามโปรดทราบว่าหากคุณใช้ TypeScript การพิมพ์ยังไม่ได้รับการอัปเดตเพื่อแสดงถึงสิ่งนี้)
devuxer

ในขณะที่เขียน xlink: href ได้รับการสนับสนุนใน Safari แต่ไม่รองรับ href
neoncube

7

หากคุณพบxlink:hrefแล้วคุณจะได้รับเทียบเท่าใน ReactJS โดยการเอาลำไส้ใหญ่และ camelcasing xlinkHrefข้อความเพิ่ม:

ในที่สุดคุณอาจใช้เนมสเปซแท็กอื่น ๆ ใน SVG เช่นxml:spaceฯลฯ กฎเดียวกันนี้ใช้กับพวกเขา (กล่าวคือxml:spaceกลายเป็นxmlSpace)


6

ดังที่ได้กล่าวไปแล้วในคำตอบของ Jon Surrell ตอนนี้รองรับการใช้แท็กแล้ว หากคุณไม่ได้ใช้ JSX คุณสามารถใช้งานได้ดังนี้:

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

0

ฉันสร้างตัวช่วยเล็ก ๆ น้อย ๆ ที่สามารถแก้ไขปัญหานี้ได้: https://www.npmjs.com/package/react-svg-use

ก่อนอื่นnpm i react-svg-use -Sก็แค่

import Icon from 'react-svg-use'

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

จากนั้นจะสร้างมาร์กอัปต่อไปนี้

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

0

SVG สามารถนำเข้าและใช้โดยตรงเป็นองค์ประกอบการตอบสนองในโค้ดการตอบสนองของคุณ

import React from 'react';
import {ReactComponent as ReactIcon} from './icon.svg';

const App = () => {
  return (
    <div className="App">
      <ReactIcon />
    </div>
  );
}
export default App;

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.