การฝัง SVG ลงใน ReactJS


127

เป็นไปได้ไหมที่จะฝังมาร์กอัป SVG ลงในคอมโพเนนต์ ReactJS

render: function() {
  return (
    <span>
      <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmln ...
    </span>
  );
}

ผลลัพธ์ในข้อผิดพลาด:

ไม่รองรับแอตทริบิวต์ Namespace ReactJSX ไม่ใช่ XML

วิธีที่เบาที่สุดในการทำคืออะไร การใช้บางอย่างเช่นReact ARTเป็นวิธีที่มากเกินไปสำหรับสิ่งที่ฉันพยายามทำ


1
คุณสามารถสร้าง jsbin ได้หรือไม่? อาจทำได้ง่ายเพียงแค่เปลี่ยนแท็ก SVG เปิดของคุณให้เป็นเพียง<svg id="Layer_1">(หรือดีกว่านั้นโดยไม่ต้องใช้รหัส) แก้ไข: นี่คือตัวอย่าง: jsbin.com/nifemuwi/2/edit?js,output
Brigand

@FakeRainBrigand ขอบคุณ! มันง่ายมากในกรณีนี้ ดูคำตอบของเบ็น นานาน่ารู้ว่าคุณสามารถแยกวิเคราะห์ jsx ได้เมื่อคุณต้องการ
nicholas

คำตอบ:


178

ปรับปรุง 2016-05-27

สำหรับ React v15 การสนับสนุน SVG ใน React นั้น (ใกล้เคียงกับ?) 100% เทียบเท่ากับเบราว์เซอร์ปัจจุบันที่รองรับ SVG ( แหล่งที่มา ) คุณเพียงแค่ต้องใช้การแปลงรูปแบบไวยากรณ์เพื่อให้เข้ากันได้กับ JSX เช่นเดียวกับที่คุณต้องทำกับ HTML ( classclassName, style="color: purple"style={{color: 'purple'}}) สำหรับแอตทริบิวต์ใด ๆ namespaced (ลำไส้ใหญ่แยก) เช่นxlink:hrefเอาและใช้ประโยชน์จากส่วนที่สองของแอตทริบิวต์เช่น: xlinkHrefนี่คือตัวอย่างของ SVG กับ<defs>, <use>และรูปแบบอินไลน์:

function SvgWithXlink (props) {
    return (
        <svg
            width="100%"
            height="100%"
            xmlns="http://www.w3.org/2000/svg"
            xmlnsXlink="http://www.w3.org/1999/xlink"
        >
            <style>
                { `.classA { fill:${props.fill} }` }
            </style>
            <defs>
                <g id="Port">
                    <circle style={{fill:'inherit'}} r="10"/>
                </g>
            </defs>

            <text y="15">black</text>
            <use x="70" y="10" xlinkHref="#Port" />
            <text y="35">{ props.fill }</text>
            <use x="70" y="30" xlinkHref="#Port" className="classA"/>
            <text y="55">blue</text>
            <use x="0" y="50" xlinkHref="#Port" style={{fill:'blue'}}/>
        </svg>
    );
}

การสาธิตรหัสการทำงาน

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการสนับสนุนเฉพาะการตรวจสอบเอกสารรายการแอตทริบิวต์ SVG สนับสนุน และนี่คือปัญหา GitHub (ปิดแล้ว) ที่ติดตามการสนับสนุนสำหรับแอตทริบิวต์ SVG เนมสเปซ


คำตอบก่อนหน้า

คุณสามารถทำการฝัง SVG แบบง่ายๆได้โดยไม่ต้องใช้dangerouslySetInnerHTMLเพียงแค่ลอกแอตทริบิวต์เนมสเปซ ตัวอย่างเช่นการทำงานนี้:

        render: function() {
            return (
                <svg viewBox="0 0 120 120">
                    <circle cx="60" cy="60" r="50"/>
                </svg>
            );
        }

เมื่อถึงจุดนั้นคุณสามารถคิดเกี่ยวกับการเพิ่มอุปกรณ์ประกอบฉากเช่นfillหรือสิ่งอื่นใดที่อาจเป็นประโยชน์ในการกำหนดค่า


@ChinonsoChukwuogor คำถามดีๆ! ฉันไม่รู้ฉันไม่เคยใช้ React Native คุณให้มันไป?
Andrew Patton

@AndrewPatton ชื่อคลาส Css หลายชื่อที่มีเครื่องหมายติ๊กไม่ทำงาน: ' .class1, .class2{fill: #005baa;}' ฉันจะแก้ไขได้อย่างไร?
HelloWorld

@HelloWorld ช่วยยกตัวอย่างหน่อยได้ไหมว่ามันใช้ไม่ได้? ฉันเพิ่งแยกการสาธิตเดิมของฉันเพื่อเพิ่มclassBและใช้งานได้: codepen.io/acusti/pen/BVJzNg
Andrew Patton

ขอบคุณเริ่มจากสิ่งนี้ฉันได้จัดการเพื่อนำเข้า svg จากไฟล์เป็นส่วนประกอบ React โดยไม่ต้องโหลดเดอร์ฉันเพิ่งลบ `` xmlns: osb = " openswatchbook.org/uri/2009/osb " `` จาก แท็ก svg เหลือเพียง xlmns ทุกอย่างเกี่ยวกับการแยกวิเคราะห์แท็กอย่างชัดเจน ในกรณีนี้ฉันได้ทำตามขั้นตอนเหล่านี้แล้วเช่นกัน: blog.logrocket.com/how-to-use-svgs-in-react
Funder

56

หากคุณมีสตริง svg แบบคงที่ที่คุณต้องการรวมคุณสามารถใช้dangerouslySetInnerHTML:

render: function() {
    return <span dangerouslySetInnerHTML={{__html: "<svg>...</svg>"}} />;
}

และ React จะรวมมาร์กอัปโดยตรงโดยไม่ต้องประมวลผลเลย


3
ฉันกำลังควบคุมบางเส้นทางภายใน SVG โดยใช้ React แต่ React ดูเหมือนจะไม่รองรับองค์ประกอบตัวกรอง มีวิธีสนับสนุนนี้หรือไม่? ดูเหมือนว่าจะเป็นอันตราย SetInnerHTML จะไม่ทำงานเพราะฉันไม่สามารถใส่ช่วงใน SVG และฉันไม่สามารถใช้เพื่อตั้งค่าแอตทริบิวต์ตัวกรองบนเส้นทาง ฉันไม่คิดว่าจะมีวิธีสร้างองค์ประกอบ React ตามปกติ แต่ให้พวกเขาส่งต่อแอตทริบิวต์ทั้งหมดแบบคำต่อคำไปยังองค์ประกอบ DOM หรือไม่
Andy

ในปี 2019 ดูเหมือนว่าคุณสามารถใช้ SetInnerHTML ที่เป็นอันตรายได้ แต่ฉันยังไม่สามารถสร้างตัวกรองเงาให้ทำงานบน Chrome โดยใช้ SetInnerHTML ที่เป็นอันตรายได้ แต่มันใช้งานได้บน Firefox
Shnd


12

หากคุณต้องการโหลดจากไฟล์คุณอาจลองใช้React-inlinesvgซึ่งค่อนข้างง่ายและตรงไปตรงมา

import SVG from 'react-inlinesvg';

<SVG
  src="/path/to/myfile.svg"
  preloader={<Loader />}
  onLoad={(src) => {
    myOnLoadHandler(src);
  }}
>
  Here's some optional content for browsers that don't support XHR or inline
  SVGs. You can use other React components here too. Here, I'll show you.
  <img src="/path/to/myfile.png" />
</SVG>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.