Wstaw HTML za pomocą instrukcji React Variable (JSX)


203

Tworzę coś z React, gdzie muszę wstawić HTML z React Variables w JSX. Czy istnieje sposób na taką zmienną:

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

i wstawić go w taki sposób, żeby działał?

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

i czy wstawia HTML zgodnie z oczekiwaniami? Nie widziałem ani nie słyszałem nic na temat funkcji reagowania, która mogłaby to zrobić bezpośrednio, lub metody analizowania rzeczy, które pozwoliłyby na to.

Odpowiedzi:


294

Możesz użyć niebezpiecznieSetInnerHTML , np

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

2
Jak to działa, jeśli musisz coś dodać <head>?
Danielle Madeley

Normalne metody DOM w componentDidMount powinny działać, ale nie robiłem tego wcześniej.
Douglas,

@DanielleMadeley Czy próbujesz wstawić warunkowe komentarze IE do <head>? Jeśli tak, odniosłem
Cam Jackson

3
Upewnij się, że przekazujesz metodę do niebezpiecznieSetInnerHTML, a nie skrótu. Według doktorów przechodzenie skrótu jest niebezpieczne. Odniesienie: facebook.github.io/react/tips/dangerously-set-inner-html.html
krytyk

1
Czy istnieje sposób bez wstawiania div?
koleś

101

Pamiętaj, że dangerouslySetInnerHTMLmoże być niebezpieczne, jeśli nie wiesz, co zawiera wstrzykiwany ciąg HTML. Wynika to z tego, że złośliwy kod po stronie klienta można wstrzykiwać za pomocą znaczników skryptu.

Prawdopodobnie dobrym pomysłem jest odkażenie łańcucha HTML za pomocą narzędzia takiego jak DOMPurify, jeśli nie masz 100% pewności, że renderowany HTML jest bezpieczny dla XSS (cross-site scripting).

Przykład:

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 nie, nie powinno :)
Artem Bernatskyi

1
czy możliwe jest renderowanie nie tylko znaczników HTML, ale także znaczników z biblioteki, takich jak znacznik alertów interfejsu użytkownika? chcę, żeby kod był takiimport 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, Czy masz jakieś rozwiązanie dla tego scenariusza?
Nimish goel

51

niebezpiecznieSetInnerHTML ma wiele wad, ponieważ znajduje się wewnątrz znacznika.

Sugeruję, abyś użył do tego jakiegoś reagującego opakowania, jak znalazłem tutaj na npm. parser HTML-Reaktywuj wykonuje tę samą pracę.

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

Bardzo prosty :)


3
„NiebezpiecznieSetInnerHTML ma wiele wad, ponieważ znajduje się wewnątrz znacznika.” Czy możesz wyjaśnić więcej na ten temat. Próbuję się zastanowić, jaka jest zasadnicza różnica między analizatorem składni HTML-sanatorizowanym a sanatized innerHtml
dchhetri

Wygląda na to, że html-reaktor-parser nie dezynfekuje danych wejściowych - zobacz FAQ
Little Brain

28

Za pomocą ''robisz to na sznurku. Użyj bez odwróconych przecinków, będzie działać dobrze.


14
Najpierw się roześmiałem, a potem dałem mu szansę, która oszalała
M na

1
Zdecydowanie najprostsza odpowiedź, zwłaszcza jeśli HTML jest napisany przez Ciebie i dynamiczny na podstawie danych wprowadzonych przez użytkownika. Możesz dosłownie ustawić var ​​myHtml = <p> Trochę tekstu </p>; i działa
pat8719

1
To najlepsza odpowiedź. Dzięki stary!
Andy Mercer

3

Aby uniknąć błędów linijek, używam go w następujący sposób:

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

Używając „” ustawia wartość na ciąg znaków, a React nie ma możliwości dowiedzenia się, że jest to element HTML. Możesz wykonać następujące czynności, aby poinformować React, że jest to element HTML -

  1. Usuń ''i to by działało
  2. Użyj, <Fragment>aby zwrócić element HTML.

2
To nie odpowiada na pytanie. Treść thisIsMyCopysama w sobie to JSX, a nie ciąg HTML. Więc dosłownie wklejasz JSX do JSX.
Antares42

Fragmenty można także znaleźć w Preact, ale tylko w wersji X i późniejszych.
Nasia Makrygianni

-3

Jeśli ktoś jeszcze tu wyląduje. Za pomocą ES6 możesz utworzyć swoją zmienną HTML tak:

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

2
a jeśli chcesz mieć zmienne w swoim łańcuchu, musisz zawinąć każdy {}i cały łańcuch w taki sposób(<span>{telephoneNumber} <br /> {email}</span>)
DanV

2
Różni się to od pytania zadanego w pytaniu. W pytaniu <p>copy copy copy <strong>strong copy</strong></p>jest ciąg. Masz go jako JSX.
YPCrumble,

4
To nie jest ES6, ale JSX
gztomas

-3

Możesz także dołączyć ten kod HTML do ReactDOM w następujący sposób:

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

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

Oto dwa linki link i link2 z dokumentacji React, które mogą być pomocne.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.