Chèn HTML với các câu lệnh biến phản ứng (JSX)


203

Tôi đang xây dựng một cái gì đó với React nơi tôi cần chèn HTML với React Variabled trong JSX. Có cách nào để có một biến như vậy không:

var thisIsMyCopy = '<p>copy copy copy <strong>strong copy</strong></p>';

và để đưa nó vào phản ứng như vậy, và nó có hoạt động không?

render: function() {
    return (
        <div className="content">{thisIsMyCopy}</div>
    );
}

và có chèn HTML như mong đợi không? Tôi chưa thấy hoặc nghe thấy bất cứ điều gì về một chức năng phản ứng có thể thực hiện nội tuyến này hoặc phương pháp phân tích cú pháp những thứ sẽ cho phép điều này hoạt động.

Câu trả lời:


294

Bạn có thể sử dụng nguy hiểmInInnerHTML , vd

render: function() {
    return (
        <div className="content" dangerouslySetInnerHTML={{__html: thisIsMyCopy}}></div>
    );
}

2
Làm thế nào để nó hoạt động nếu bạn cần thêm một cái gì đó <head>?
Danielle Madeley

Các phương thức DOM thông thường trong componentDidMount sẽ hoạt động, mặc dù tôi chưa từng làm điều đó trước đây.
Douglas

@DanielleMadeley Bạn đang cố gắng chèn bình luận IE có điều kiện vào <head>? Nếu vậy, tôi đã thành công khi sử dụng thủ thuật được mô tả ở đây: nemisj.com/conditable-ie-comments-in-react-js
Cam Jackson

3
Hãy chắc chắn rằng bạn truyền một phương thức cho nguy hiểm SetInnerHTML chứ không phải là hàm băm. Theo các tài liệu, thật nguy hiểm khi chỉ cần vượt qua một hàm băm. Tham khảo: facebook.github.io/react/tips/dangeriously-set-inner-html.html
criticerz

1
Có cách nào mà không chèn div?
anh chàng

101

Lưu ý rằng dangerouslySetInnerHTMLcó thể nguy hiểm nếu bạn không biết những gì trong chuỗi HTML bạn đang tiêm. Điều này là do mã phía máy khách độc hại có thể được tiêm thông qua các thẻ script.

Có lẽ là một ý tưởng tốt để vệ sinh chuỗi HTML thông qua một tiện ích như DOMPurify nếu bạn không chắc chắn 100% HTML mà bạn đang hiển thị là XSS (kịch bản chéo trang) an toàn.

Thí dụ:

import DOMPurify from 'dompurify'

const thisIsMyCopy = '<p>copy copy copy <strong>strong copy</strong></p>';


render: function() {
    return (
        <div className="content" dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(thisIsMyCopy)}}></div>
    );
}

@vsync nope nó không nên :)
Artem Bernatskyi

1
có thể kết xuất không chỉ các thẻ html mà cả thẻ từ thư viện như thẻ thông báo ui. tôi muốn mã giống như thế nàyimport DOMPurify from 'dompurify' const thisIsMyCopy = '<Alert severity="warning">copy copy copy <strong>strong copy</strong></Alert >'; render: function() { return ( <div className="content" dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(thisIsMyCopy)}}></div> ); }
sasha romanov

@sasharomanov, bạn đã có giải pháp nào cho kịch bản này chưa?
Nimish goel

51

nguy hiểm SetInnerHTML có nhiều bất lợi vì nó được đặt bên trong thẻ.

Tôi đề nghị bạn sử dụng một số trình bao bọc phản ứng như tôi đã tìm thấy ở đây trên npm cho mục đích này. html-Reac-Parser thực hiện cùng một công việc.

import Parser from 'html-react-parser';
var thisIsMyCopy = '<p>copy copy copy <strong>strong copy</strong></p>';


render: function() {
    return (
        <div className="content">{Parser(thisIsMyCopy)}</div>
    );
}

Rất đơn giản :)


3
"Nguy hiểm SetInnerHTML có nhiều bất lợi vì nó được đặt bên trong thẻ." Bạn có thể giải thích thêm về điều này. Cố gắng nghĩ xem có sự khác biệt cơ bản nào giữa html-Reac-Parser và sanatized InsideHtml
dchhetri 29/03/18

Có vẻ như trình phân tích cú pháp phản ứng html không vệ sinh đầu vào - xem Câu hỏi thường gặp
Little Brain

28

Bằng cách sử dụng, ''bạn đang làm cho nó thành chuỗi. Sử dụng mà không có dấu phẩy đảo ngược nó sẽ hoạt động tốt.


14
Lúc đầu, tôi đã cười và sau đó cho nó một cơ hội làm tôi suy nghĩ
M vào

1
Cho đến nay, câu trả lời đơn giản nhất là HTML được viết bởi bạn và năng động dựa trên đầu vào của người dùng. Bạn hoàn toàn có thể đặt var myHtml = <p> Một số văn bản </ p>; và nó hoạt động
pat8719

1
Đây là câu trả lời tốt nhất. Cảm ơn, bạn đời!
Andy Mercer

3

Để tránh lỗi kẻ nói dối, tôi sử dụng nó như thế này:

  render() {
    const props = {
      dangerouslySetInnerHTML: { __html: '<br/>' },
    };
    return (
        <div {...props}></div>
    );
  }

3
import { Fragment } from 'react' // react version > 16.0

var thisIsMyCopy = (
  <Fragment>
    <p>copy copy copy&nbsp;
    <strong>strong copy</strong>
    </p>
  </Fragment>
)

Bằng cách sử dụng '', đặt giá trị thành một chuỗi và React không có cách nào biết rằng đó là một phần tử HTML. Bạn có thể làm như sau để cho React biết đó là một phần tử HTML -

  1. Hủy bỏ ''và nó sẽ làm việc
  2. Sử dụng <Fragment>để trả về một phần tử HTML.

2
Điều này không trả lời câu hỏi. Nội dung của thisIsMyCopychính nó là JSX, không phải là một chuỗi HTML. Vì vậy, bạn thực sự dán JSX vào JSX.
Antares42

Bạn cũng có thể tìm thấy Fragment trong Preact nhưng chỉ trong phiên bản X trở đi.
Nasia Makrygianni

-3

Nếu ai khác vẫn hạ cánh ở đây. Với ES6, bạn có thể tạo biến html của mình như vậy:

render(){
    var thisIsMyCopy = (
        <p>copy copy copy <strong>strong copy</strong></p>
    );
    return(
        <div>
            {thisIsMyCopy}
        </div>
    )
}

2
và nếu bạn muốn các biến trong chuỗi của mình, bạn sẽ cần phải bọc từng {}chuỗi và toàn bộ chuỗi trong một số đánh dấu như vậy(<span>{telephoneNumber} <br /> {email}</span>)
DanV

2
Điều này khác với những gì được hỏi trong câu hỏi. Trong câu hỏi <p>copy copy copy <strong>strong copy</strong></p>là một chuỗi. Bạn có nó là JSX.
YPCrumble

4
Đó không phải là ES6, mà là JSX
gztomas

-3

Bạn cũng có thể đưa HTML này vào ReactDOM như thế này:

var thisIsMyCopy = (<p>copy copy copy <strong>strong copy</strong></p>);

ReactDOM.render(<div className="content">{thisIsMyCopy}</div>, document.getElementById('app'));

Dưới đây là hai liên kết liên kếtlink2 từ tài liệu React có thể hữu ích.

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.