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.

Respostas:


295

Você pode usar perigosamente o SetInnerHTML , por exemplo,

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

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

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


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.


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

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.

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

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.