Inserir HTML com React Variable Statements (JSX)

203

Estou criando algo com React, onde preciso inserir HTML com React Variables em JSX. Existe uma maneira de ter uma variável assim:

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

e inseri-lo em reagir assim, e funcionou?

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

e ele insere o HTML conforme o esperado? Não vi nem ouvi nada sobre uma função de reação que pudesse fazer isso em linha ou sobre um método de analisar coisas que permitiriam que isso funcionasse.

Kyle Hotchkiss
fonte

Respostas:

295

Você pode usar perigosamente o SetInnerHTML , por exemplo,

render: function() {
    return (
        <div className="content" dangerouslySetInnerHTML={{__html: thisIsMyCopy}}></div>
    );
}
Douglas
fonte
2
Como isso funciona se você precisar adicionar algo <head>?
Danielle Madeley
Métodos DOM normais em componentDidMount devem funcionar, embora eu não tenha feito isso antes.
Douglas
@DanielleMadeley Você está tentando inserir comentários condicionais do IE em <head>? Se assim for, eu tive sucesso usando o truque descrito aqui: nemisj.com/conditional-ie-comments-in-react-js
Cam Jackson
3
Certifique-se de passar um método para o perigosamente SetInnerHTML e não um hash. De acordo com os documentos, é perigoso apenas passar um hash. Referência: facebook.github.io/react/tips/dangerously-set-inner-html.html
criticerz
1
Existe uma maneira de inserir o div?
cara
102

Observe que isso dangerouslySetInnerHTMLpode ser perigoso se você não souber o que está na cadeia HTML que está injetando. Isso ocorre porque o código malicioso do lado do cliente pode ser injetado por meio de tags de script.

Provavelmente, é uma boa ideia higienizar a string HTML por meio de um utilitário como DOMPurify, se você não tiver 100% de certeza de que o HTML que você está processando é seguro para XSS (cross-site scripting).

Exemplo:

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>
    );
}
Yo Wakita
fonte
@vsync Nope ele não deve :)
Artem Bernatskyi
1
é possível renderizar não apenas tags html, mas também da biblioteca como a tag Alert ui material. Eu quero que o código seja assimimport 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 24/04
@sasharomanov, Você conseguiu alguma solução para esse cenário?
Nimish goel
51

dangerouslySetInnerHTML tem muitas desvantagens, pois é definido dentro da tag.

Eu sugiro que você use algum wrapper de reação como o que encontrei aqui no npm para esse fim. html-react-parser faz o mesmo trabalho.

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

Muito simples :)

user2903536
fonte
3
"dangerouslySetInnerHTML tem muitas desvantagens porque é definido dentro da tag." Você pode explicar mais sobre isso? Tentando pensar o que diferença fundamental que existe entre html-reagem-parser e sanatized innerHTML
dchhetri
Parece que o html-react-parser não higieniza a entrada - consulte a FAQ
Little Brain
28

Usando ''você está fazendo isso para string. Use sem vírgulas invertidas, funcionará bem.

iamnotbatma
fonte
14
No começo eu riu e, em seguida, deu-lhe a chance que soprar minha mente
M em
1
De longe, a resposta mais simples, especialmente se o HTML for escrito por você e dinâmico com base na entrada do usuário. Você pode literalmente definir var myHtml = <p> Algum texto </p>; e funciona
pat8719 15/05/19
1
Esta é a melhor resposta. Obrigado, companheiro!
Andy Mercer
3

Para evitar erros de linter, eu o uso assim:

  render() {
    const props = {
      dangerouslySetInnerHTML: { __html: '<br/>' },
    };
    return (
        <div {...props}></div>
    );
  }
Tudor Morar
fonte
3
import { Fragment } from 'react' // react version > 16.0

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

Ao usar '', o valor é definido como uma sequência e o React não tem como saber que é um elemento HTML. Você pode fazer o seguinte para que o React saiba que é um elemento HTML -

  1. Remova o ''e funcionaria
  2. Use <Fragment>para retornar um elemento HTML.
Amandeep Singh Ghai
fonte
2
Isso não responde à pergunta. O próprio conteúdo thisIsMyCopyé JSX, não uma sequência de HTML. Então, você está literalmente colando JSX no JSX.
Antares42,
Você pode encontrar fragmentos no Preact também, mas apenas na versão X e diante.
Nasia Makrygianni
-3

Se mais alguém ainda pousar aqui. Com o ES6, você pode criar sua variável html da seguinte forma:

render(){
    var thisIsMyCopy = (
        <p>copy copy copy <strong>strong copy</strong></p>
    );
    return(
        <div>
            {thisIsMyCopy}
        </div>
    )
}
atormentar
fonte
2
e se você quiser variáveis ​​dentro da sua string, precisará envolver cada uma delas {}e toda a string em alguma marcação como essa #(<span>{telephoneNumber} <br /> {email}</span>)
DanV
2
Isso é diferente do que é solicitado na pergunta. Na questão <p>copy copy copy <strong>strong copy</strong></p>é uma string. Você o tem como JSX.
YPCrumble
4
Isso não é ES6, mas JSX
gztomas
-3

Você também pode incluir esse HTML no ReactDOM assim:

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

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

Aqui estão dois links link e link2 da documentação do React que podem ser úteis.

GrassLand
fonte