Вставьте HTML с React Variable Statements (JSX)

204

Я строю что-то с React, где мне нужно вставить HTML с переменными React в JSX. Есть ли способ иметь переменную так:

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

и вставить его в реакцию, как это так, и это работает?

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

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

Кайл Хотчкисс
источник

Ответы:

298

Вы можете использовать опасно SetInnerHTML , например,

render: function() {
    return (
        <div className="content" dangerouslySetInnerHTML={{__html: thisIsMyCopy}}></div>
    );
}
Дуглас
источник
2
Как это работает, если вам нужно что-то добавить <head>?
Даниэль Мадли
Обычные методы DOM в componentDidMount должны работать, хотя я раньше этого не делал.
Дуглас
@DanielleMadeley Вы пытаетесь вставить условные комментарии IE в <head>? Если так, у меня был успех, используя уловку, описанную здесь: nemisj.com/conditional-ie-comments-in-react-js
Кэм Джексон
3
Удостоверьтесь, что вы передаете метод опасно SetInnerHTML, а не хэш. Согласно документации, опасно просто передавать хеш. Ссылка: facebook.github.io/react/tips/dangerously-set-inner-html.html
критик
1
Есть ли способ без вставки div?
чувак
102

Обратите внимание, что это 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 Нет, не должно :)
Артем Бернацкий
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

dangerouslySetInnerHTML имеет много недостатков, потому что он установлен внутри тега.

Я предлагаю вам использовать какую-нибудь реактивную оболочку, как я нашел здесь для npm. html-реагировать-парсер делает ту же работу.

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

Очень просто :)

user2903536
источник
3
«dangerouslySetInnerHTML имеет много недостатков, потому что он установлен внутри тега». Можете ли вы объяснить больше об этом? Попытка понять, в чем принципиальная разница между html-реагирующим парсером и санацией innerHtml
dchhetri
Кажется, что html-реагировать-парсер не дезинфицирует ввод - см. FAQ
Little Brain
28

Используя его, ''вы превращаете его в строку. Используйте без кавычек, он будет работать нормально.

iamnotbatma
источник
14
Сначала я смеялся, а затем дал ему шанс, который
М в
1
Безусловно, самый простой ответ, особенно если HTML написан вами и динамически основан на пользовательском вводе. Вы можете буквально установить var myHtml = <p> Some text </ 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
Вы также можете найти фрагменты в Preact, но только в версии 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'));

Вот две ссылки link и link2 из документации React, которые могут быть полезны.

пастбище
источник