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.

Respuestas:


296

Puede usar dangerouslySetInnerHTML , por ejemplo

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

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

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


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.


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

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.

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

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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.