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.