Вставити HTML з реагуючими змінними (JSX)


203

Я будую щось із React, куди мені потрібно вставити HTML із змінними React у JSX. Чи існує спосіб мати змінну на зразок такої:

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

і вставити його в такий відреагувати, і чи спрацює це?

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

і чи вставити він HTML, як очікувалося? Я не бачив і не чув нічого про функцію реагування, яка могла б зробити це вбудованим способом, або метод розбору речей, які дозволяли б цьому працювати.

Відповіді:


294

Ви можете використовувати небезпечноSetInnerHTML , наприклад,

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

2
Як це працює, якщо вам потрібно щось додати <head>?
Даніель Мадлі

Нормальні методи DOM у компонентіDidMount повинні працювати, я ще цього не робив.
Дуглас

@DanielleMadeley Ви намагаєтесь вставити умовні коментарі IE до <head>? Якщо так, я мав успіх, використовуючи описаний тут трюк: nemisj.com/conditional-ie-comments-in-react-js
Cam Jackson

3
Переконайтеся, що ви передаєте метод небезпечноSetInnerHTML, а не хеш. Згідно з документами, небезпечно просто передавати хеш. Довідка: facebook.github.io/react/tips/dangerously-set-inner-html.html
kriticerz

1
Чи є спосіб, не вставляючи div?
чувак

101

Зауважте, що це dangerouslySetInnerHTMLможе бути небезпечно, якщо ви не знаєте, що знаходиться в рядку HTML, який ви вводите. Це пов’язано з тим, що зловмисний код на стороні клієнта може бути введений за допомогою тегів сценарію.

Це, мабуть, гарна ідея очистити HTML-рядок за допомогою такої утиліти, як DOMPurify, якщо ви не впевнені на 100%, що HTML, який ви надаєте, є безпечним для XSS (міжсайтового сценарію).

Приклад:

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 це не повинно :)
Артем Бернацький

1
чи можна візуалізувати не тільки теги HTML, але і теги з бібліотеки, як матеріал ui Тег сповіщення. Я хочу, щоб код був таким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> ); }
Саша Романов

@sasharomanov, Ви отримали рішення для цього сценарію?
Німішський гольль

51

небезпечноSetInnerHTML має багато недоліків, оскільки він встановлений всередині тегу.

Я пропоную вам скористатись такою реактивною обгорткою, як я знайшов її для npm для цієї мети. html-react-аналізатор виконує ту саму роботу.

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

Дуже просто :)


3
"небезпечноSetInnerHTML має багато недоліків, оскільки він встановлений всередині тегу." Чи можете ви пояснити більше про це. Намагаючись придумати, яка принципова різниця є між html-react-parser та санатизованим InternalHtml
dchhetri

Здається, що html-react-аналізатор не санітує вхід - дивіться FAQ
Little Brain

28

Використовуючи, ''ви перетворюєте його на рядок. Використовуйте без перевернутих коми, це буде добре.


14
Спочатку я сміявся, а потім дав йому шанс, який вдарить мені в голову
M

1
На сьогодні найпростіша відповідь, особливо якщо HTML написаний вами та динамічний на основі введення користувача. Ви можете досить буквально встановити var myHtml = <p> Якийсь текст </p>; і працює
pat8719

1
Це найкраща відповідь. Дякую, друже!
Енді Мерсер

3

Щоб уникнути помилок лінійки, я використовую його так:

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

Використовуючи '' встановлює значення для рядка, і React не може знати, що це HTML-елемент. Ви можете зробити наступне, щоб React дізнався, що це елемент HTML -

  1. Видаліть ''і воно буде працювати
  2. Використовуйте <Fragment>для повернення елемента HTML.

2
Це не дає відповіді на запитання. Зміст thisIsMyCopyсам по собі JSX, а не рядок HTML. Таким чином, ви буквально вставляєте JSX в JSX.
Antares42

Ви також можете знайти фрагменти в Заповіді, але лише у версії X і далі.
Nasia Makrygianni

-3

Якщо хтось ще приземлиться тут. За допомогою ES6 ви можете створити вашу HTML-змінну так:

render(){
    var thisIsMyCopy = (
        <p>copy copy copy <strong>strong copy</strong></p>
    );
    return(
        <div>
            {thisIsMyCopy}
        </div>
    )
}

2
і якщо ви хочете, щоб змінні всередині рядка вам потрібно було обернути кожну {}і всю рядку в такій розмітці, як так(<span>{telephoneNumber} <br /> {email}</span>)
DanV

2
Це відрізняється від того, що задано у питанні. У питанні <p>copy copy copy <strong>strong copy</strong></p>- рядок. У вас це як JSX.
YPCrumble

4
Це не ES6, а JSX
gztomas

-3

Ви також можете включити цей HTML в ReactDOM так:

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

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

Ось два посилання та link2 з документації React, які можуть бути корисними.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.