Nhúng SVG vào ReactJS


127

Có thể nhúng đánh dấu SVG vào thành phần ReactJS không?

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

Kết quả là lỗi:

Thuộc tính không gian tên không được hỗ trợ. ReactJSX không phải là XML.

Cách nhẹ nhất để làm điều này là gì. Sử dụng một cái gì đó như React ART là quá mức cần thiết cho những gì tôi đang cố gắng làm.


1
Bạn có thể tạo một jsbin? Nó có thể đơn giản như thay đổi thẻ SVG mở của bạn thành chỉ <svg id="Layer_1">(hoặc thậm chí tốt hơn, không có id). Chỉnh sửa: đây là một ví dụ: jsbin.com/nifemuwi/2/edit?js,output
Brigand

@FakeRainBrigand Cảm ơn! Đó là đơn giản trong trường hợp này. Nhìn vào câu trả lời của Ben mặc dù. Điều tốt để biết bạn có thể nhận được xung quanh phân tích cú pháp jsx khi bạn cần.
nicholas

Câu trả lời:


178

Cập nhật 2016-05-27

Kể từ React v15, hỗ trợ cho SVG trong React là (gần bằng?) Chẵn lẻ 100% với hỗ trợ trình duyệt hiện tại cho SVG ( nguồn ). Bạn chỉ cần áp dụng một số chuyển đổi cú pháp để làm cho nó tương thích với JSX, giống như bạn đã phải làm với HTML ( classclassName, style="color: purple"style={{color: 'purple'}}). Đối với bất kỳ namespaced thuộc tính (dấu hai chấm-tách ra), ví dụ xlink:href, hãy tháo :và tận dụng phần thứ hai của thuộc tính, ví dụ xlinkHref. Dưới đây là một ví dụ về một svg với <defs>, <use>và phong cách nội tuyến:

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>
    );
}

Bản demo làm việc

Để biết thêm chi tiết về hỗ trợ cụ thể, hãy kiểm tra danh sách các thuộc tính SVG được hỗ trợ của tài liệu . Và đây là vấn đề GitHub (hiện đã đóng) đã theo dõi hỗ trợ cho các thuộc tính SVG được đặt tên.


Câu trả lời trước

Bạn có thể thực hiện một nhúng SVG đơn giản mà không cần phải sử dụng dangerouslySetInnerHTMLbằng cách chỉ tước các thuộc tính không gian tên. Ví dụ, điều này hoạt động:

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

Tại thời điểm nào bạn có thể nghĩ về việc thêm các đạo cụ như fill, hoặc bất cứ điều gì khác có thể hữu ích để cấu hình.


@ChinonsoChukwuogor Câu hỏi tuyệt vời! Tôi không biết, tôi chưa bao giờ sử dụng React Native. Bạn đã cho nó đi?
Andrew Patton

@AndrewPatton Nhiều tên lớp Css với dấu tick char không hoạt động: ' .class1, .class2{fill: #005baa;}' Làm thế nào tôi có thể sửa nó?
HelloWorld

@HelloWorld Bạn có thể cho tôi một ví dụ về việc nó không hoạt động không? Tôi vừa rẽ nhánh bản demo ban đầu của mình để thêm classBvà nó hoạt động: codepen.io/acusti/pen/BVJzNg
Andrew Patton

Cảm ơn, bắt đầu từ việc này, tôi đã quản lý để nhập một Svg từ tệp dưới dạng thành phần React mà không cần bất kỳ trình tải nào, tôi vừa xóa `` `xmlns: osb =" openswatchbook.org/uri/2009/osb "` `` từ thẻ svg, chỉ để lại xlmns. Đó là tất cả về phân tích thẻ rõ ràng. Chỉ trong trường hợp, tôi cũng đã làm theo các bước sau: blog.logrocket.com/how-to-use-svgs-in-react
Nhà tài trợ

56

Nếu bạn chỉ có một chuỗi svg tĩnh bạn muốn đưa vào, bạn có thể sử dụng dangerouslySetInnerHTML:

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

và React sẽ bao gồm đánh dấu trực tiếp mà không xử lý nó.


3
Tôi đang kiểm soát một số đường dẫn bên trong SVG bằng React, nhưng React dường như không hỗ trợ các thành phần bộ lọc. Có cách nào để hỗ trợ điều này? Có vẻ như nguy hiểm SetInnerHTML sẽ không hoạt động vì tôi không thể đặt một khoảng bên trong một SVG và tôi không thể sử dụng điều đó để đặt thuộc tính bộ lọc trên các đường dẫn. Tôi không cho rằng có cách tạo các phần tử React như bình thường nhưng chúng có chuyển tất cả các thuộc tính nguyên văn cho các phần tử DOM không?
Andy

Vào năm 2019, dường như bạn có thể sử dụng nguy hiểm SetInnerHTML nhưng tôi vẫn không thể tạo bộ lọc bóng để hoạt động trên Chrome bằng cách sử dụng nguy hiểm SetInnerHTML, nhưng nó hoạt động trên Firefox.
Shnd

31

Theo một nhà phát triển phản ứng , bạn không cần xmlns không gian tên. Nếu bạn cần thuộc tính, xlink:hrefbạn có thể sử dụng xlinkHref từ phản ứng 0.14

Thí dụ

Icon = (props) => {
  return <svg className="icon">
    <use xlinkHref={ '#' + props.name }></use>
  </svg>;
}

12

Nếu bạn muốn tải nó từ một tệp, bạn có thể thử sử dụng React-inlinesvg - điều đó khá đơn giản và dễ hiểu.

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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.