Insertar HTML con React Variable Statements (JSX)

204

Estoy creando algo con React donde necesito insertar HTML con React Variables en JSX. ¿Hay alguna manera de tener una variable como esta?

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

e insertarlo en reaccionar así, ¿y hacer que funcione?

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

y tiene que insertar el HTML como se esperaba? No he visto ni escuchado nada acerca de una función de reacción que pueda hacer esto en línea, o un método de analizar cosas que permitan que esto funcione.

Kyle Hotchkiss
fuente

Respuestas:

296

Puede usar dangerouslySetInnerHTML , por ejemplo

render: function() {
    return (
        <div className="content" dangerouslySetInnerHTML={{__html: thisIsMyCopy}}></div>
    );
}
Douglas
fuente
2
¿Cómo funciona esto si necesita agregar algo <head>?
Danielle Madeley
Los métodos DOM normales en componentDidMount deberían funcionar, aunque no lo he hecho antes.
Douglas
@DanielleMadeley ¿Está intentando insertar comentarios condicionales de IE en <head>? Si es así, he tenido éxito usando el truco descrito aquí: nemisj.com/conditional-ie-comments-in-react-js
Cam Jackson
3
Asegúrese de pasar un método al dangerouslySetInnerHTML y no un hash. Según los documentos, es peligroso pasar un hash. Referencia: facebook.github.io/react/tips/dangerously-set-inner-html.html
criticador
1
¿Hay alguna manera sin insertar el div?
amigo
102

Tenga en cuenta que dangerouslySetInnerHTMLpuede ser peligroso si no sabe qué hay en la cadena HTML que está inyectando.Esto se debe a que el código malicioso del lado del cliente se puede inyectar a través de etiquetas de script.

Probablemente sea una buena idea desinfectar la cadena HTML a través de una utilidad como DOMPurify si no está 100% seguro de que el HTML que está renderizando es seguro XSS (cross-site scripting).

Ejemplo:

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
fuente
@vsync no, no debería :)
Artem Bernatskyi
1
¿Es posible renderizar no solo etiquetas html sino también etiquetas de la biblioteca como material ui Alert tag. quiero que el código sea asíimport 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, ¿Obtuviste alguna solución para este escenario?
Nimish goel
51

dangerouslySetInnerHTML tiene muchas desventajas porque se establece dentro de la etiqueta.

Le sugiero que use un contenedor de reacción como encontré uno aquí en npm para este propósito. html-react-parser hace el mismo trabajo.

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

Muy simple :)

usuario2903536
fuente
3
"dangerouslySetInnerHTML tiene muchas desventajas porque se establece dentro de la etiqueta". ¿Puedes explicar más sobre esto? Tratando de pensar qué diferencia fundamental hay entre html-react-parser y innerHtml sanatizado
dchhetri
Parece que html-react-parser no desinfecta la entrada; consulte las preguntas frecuentes
Little Brain,
28

Al usarlo ''lo estás haciendo en cadena. Usar sin comillas invertidas funcionará bien.

iamnotbatma
fuente
14
Al principio me reí y luego le di una oportunidad que me dejó boquiabierto
M el
1
Con mucho, la respuesta más simple, especialmente si el HTML está escrito por usted y es dinámico según la entrada del usuario. Literalmente, puede establecer var myHtml = <p> Algún texto </p>; y funciona
pat8719
1
Esta es la mejor respuesta. ¡Gracias amigo!
Andy Mercer
3

Para evitar errores de linter, lo uso así:

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

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

Al usar '', establece el valor en una cadena y React no tiene forma de saber que es un elemento HTML. Puede hacer lo siguiente para que React sepa que es un elemento HTML:

  1. Retire el ''y funcionaría
  2. Use <Fragment>para devolver un elemento HTML.
Amandeep Singh Ghai
fuente
2
Esto no responde la pregunta. El contenido de thisIsMyCopysí mismo es JSX, no una cadena de HTML. Así que literalmente estás pegando JSX en JSX.
Antares42
También puede encontrar Fragmentos en Preact, pero solo en la versión X y posteriores.
Nasia Makrygianni
-3

Si alguien más todavía aterriza aquí. Con ES6 puede crear su variable html de esta manera:

render(){
    var thisIsMyCopy = (
        <p>copy copy copy <strong>strong copy</strong></p>
    );
    return(
        <div>
            {thisIsMyCopy}
        </div>
    )
}
Harry
fuente
2
y si desea variables dentro de su cadena, necesitará envolver cada una {}y toda la cadena en un marcado como tal(<span>{telephoneNumber} <br /> {email}</span>)
DanV
2
Esto es diferente de lo que se pregunta en la pregunta. En la pregunta <p>copy copy copy <strong>strong copy</strong></p>hay una cadena. Lo tienes como JSX.
YPCrumble
44
Eso no es ES6, sino JSX
gztomas
-3

También puede incluir este HTML en ReactDOM de esta manera:

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

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

Aquí hay dos enlaces link y link2 de la documentación de React que podrían ser útiles.

Pradera
fuente