React - Як передавати теги HTML у реквізиті?


118

Я хочу мати можливість передавати текст із тегами HTML, наприклад:

<MyComponent text="This is <strong>not</strong> working." />

Але всередині MyComponentметоду візуалізації, коли я роздруковую this.props.text, він буквально роздруковує все:

This is <strong>not</strong> working.

Чи є спосіб зробити React розбору HTML і скинути його належним чином?


Яка ваша фактична функція візуалізації?
Луціо

3
Типовим зразком буде те, щоб зробити вміст дітьми свого компонента <MyComponent>This is <strong>not</strong> working</MyComponent>, а не передавати їх як реквізит. Чи можете ви дати більше контексту щодо того, що ви насправді намагаєтесь досягти?
Нік Томлін

Майже те саме питання: Reactjs конвертувати в html .
totymedli

Відповіді:


140

Ви можете використовувати змішані масиви з рядками та елементами JSX (див. Документи тут ):

<MyComponent text={["This is ", <strong>not</strong>,  "working."]} />

Тут є загадка, яка показує, що вона працює: http://jsfiddle.net/7s7dee6L/

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


10
Це працює, за винятком того, що я отримую попередження: Попередження: Кожна дитина в масиві чи ітераторі повинна мати унікальну опору "ключ". Перевірте метод візуалізації CTA. Це було передано дитиною з Шаблону1. Див. Fb.me/react-warning-keys для отримання додаткової інформації.
ffxsam

3
Ви можете усунути цю помилку, пройшовши масив і додавши індекс як ключ в MyComponent {text.map( textOrHTML, index) => <span key={index}>{textOrHTML}</span> )} Хоча це просто так дивно, що нам це потрібно робити в першу чергу цілком.
HussienK

5
Ви можете також встановити попередження, поставивши key="[some unique value]"на <strong>елемент.
Чад Джонсон

Приємно, добре працюючи, я хотів би знати, як я можу використовувати змінну всередині сильної замість рядка "не"
Jaison

2
Для того, щоб видалити попередження ключа масиву, тепер також можна передавати один JSX подібний. <MyComponent text={<>This is <strong>not</strong> working.</>} />
Аріф

111

Насправді, існує кілька способів досягти цього.

Ви хочете використовувати JSX всередині реквізиту

Ви можете просто використовувати {}, щоб JSX розібрав параметр. Єдине обмеження таке ж, як і для кожного елемента JSX: Він повинен повертати лише один кореневий елемент.

myProp={<div><SomeComponent>Some String</div>}

Найкращий спосіб для цього читати - це створити функцію renderMyProp, яка повертає компоненти JSX (як і стандартну функцію візуалізації), а потім просто викликає myProp = {this.renderMyProp ()}

Ви хочете передати лише HTML як рядок

За замовчуванням JSX не дозволяє вам виводити необроблений HTML із рядкових значень. Однак є спосіб зробити так:

myProp="<div>This is some html</div>"

Тоді у своєму компоненті ви можете використовувати його так:

<div dangerouslySetInnerHTML=myProp={{ __html: this.renderMyProp() }}></div>

Будьте уважні, що це рішення "може" відкритися на міжсайтових сценаріях атак підробків. Також майте на увазі, що ви можете візуалізувати лише простий HTML, без тегів або компонентів JSX або інших химерних речей.

Шлях масиву

Реагуючи, ви можете передавати масив елементів JSX. Це означає:

myProp={["This is html", <span>Some other</span>, "and again some other"]}

Я б не рекомендував цей метод, оскільки:

  • Це створить попередження (відсутні клавіші)
  • Це не читабельно
  • Це насправді не JSX спосіб, це більше хак, ніж призначений дизайн.

Діти так

Додавши його заради повноти, але реагуючи, ви також можете отримати всіх дітей, які знаходяться у вашому компоненті.

Тож якщо я беру такий код:

<SomeComponent>
    <div>Some content</div>
    <div>Some content</div>
</SomeComponent>

Тоді два діви будуть доступні як this.props.children в SomeComponent і можуть бути надані зі стандартним {} синтаксисом.

Це рішення є ідеальним, коли у вас є лише один вміст HTML для передачі вашому компоненту (уявіть собі компонент Popin, який приймає вміст Popin лише як діти).

Однак якщо у вас є декілька вмісту, ви не можете використовувати дітей (або вам потрібно принаймні поєднувати його з іншим рішенням тут)


1
this.props.childrens - але this.props.children. Без 's' reactjs.org/docs/glossary.html#propschildren
Alexiuscrow

13

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

Просто надішліть HTML як звичайний рядок

<MyComponent text="This is <strong>not</strong> working." />

І візуалізуйте в коді JSX так:

<h2 className="header-title-right wow fadeInRight"
    dangerouslySetInnerHTML={{__html: props.text}} />

Будьте обережні, якщо ви передаєте дані, введені користувачем. Ви можете стати жертвою нападу XSS

Ось документація: https://facebook.github.io/react/tips/dangerously-set-inner-html.html


7
<MyComponent text={<span>This is <strong>not</strong> working.</span>} />

а потім у своєму компоненті ви можете виконати перевірку підтримки таким чином:

import React from 'react';
export default class MyComponent extends React.Component {
  static get propTypes() {
    return {
      text: React.PropTypes.object, // if you always want react components
      text: React.PropTypes.any, // if you want both text or react components
    }
  }
}

Переконайтесь, що ви вибрали лише один тип опори.


6

Для мене це спрацювало, передаючи html-тег у дітей реквізиту

<MyComponent>This is <strong>not</strong> working.</MyComponent>


var MyComponent = React.createClass({

   render: function() {
    return (
      <div>this.props.children</div>
    );
   },


6

У програмі реагування на стороні клієнта є кілька способів надання опори у вигляді рядка з деяким html. Один безпечніший за інший ...

1 - Визначте опору як jsx (моє уподобання)

const someProps = {
  greeting: {<div>Hello<a href="/${name_profile}">${name_profile}</a></div>}
}


const GreetingComopnent = props => (
  <p>{props.someProps.greeting}</p>
)

• Єдина вимога тут полягає в тому, що будь-який файл, що генерує цю опору, повинен включати React як залежність (на випадок, якщо ви генеруєте jsx реквізиту у файлі помічника тощо).

2 - небезпечно встановити внутрішній Html

const someProps = {
  greeting: '<React.Fragment>Hello<a href="https://stackoverflow.com/${name_profile}">${name_profile}</a></React.Fragment>'
}

const GreetingComponent = props => {
  const innerHtml = { __html: props.someProps.greeting }
  return <p dangerouslySetInnerHtml={innerHtml}></p>
}

• Цей другий підхід не рекомендує. Уявіть поле введення, значення введення якого відображається як опора в цьому компоненті. Користувач може ввести тег скрипту у вхід, і компонент, який надає цей вхід, виконає цей потенційно шкідливий код. Таким чином, такий підхід має потенціал для впровадження вразливих сценаріїв міжсайтового сценарію. Для отримання додаткової інформації зверніться до офіційних документів React



3

Ви можете це зробити двома способами, про які я знаю.

1- <MyComponent text={<p>This is <strong>not</strong> working.</p>} />

А потім зробіть це

class MyComponent extends React.Component {
   render () {
     return (<div>{this.props.text}</div>)
   }
}

Або другий підхід робити це так

2- <MyComponent><p>This is <strong>not</strong> working.</p><MyComponent/>

А потім зробіть це

class MyComponent extends React.Component {
   render () {
     return (<div>{this.props.children}</div>)
   }
}

1
Я додав змінну let vhtml = "<p>Test</p>"і використав її на опорі, як це, text={vhtml}і вона все ще відображається у простому тексті чомусь.
Si8

2

@matagus відповідь для мене добре, сподіваюся, що нижче фрагмент допомагає тим, хто бажає використовувати змінну всередині.

const myVar = 'not';
<MyComponent text={["This is ", <strong>{`${myVar}`}</strong>,  "working."]} />

1

У своєму проекті мені довелося передати динамічний фрагмент html від змінної та віддати його всередині компонента. Тому я зробив наступне.

defaultSelection : {
    innerHtml: {__html: '<strong>some text</strong>'}
}

defaultSelection об'єкт передається компоненту з .jsфайлу

<HtmlSnippet innerHtml={defaultSelection.innerHtml} />

Компонент HtmlSnippet

var HtmlSnippet = React.createClass({
  render: function() {
    return (
      <span dangerouslySetInnerHTML={this.props.innerHtml}></span>
    );
  }
});

Приклад Плункр

реагувати док на небезпечноSetInnerHTML


1

Ви також можете використовувати функцію компонента, щоб перейти по jsx через реквізити. подібно до:

 var MyComponent = React.createClass({

   render: function() {
    return (
      <OtherComponent
        body={this.body}
      />
    );
   },

   body() {
     return(
       <p>This is <strong>now</strong> working.<p>
     );
   }

});

var OtherComponent = React.createClass({

  propTypes: {
    body: React.PropTypes.func
  },

  render: function() {
     return (
        <section>
          {this.props.body()}
        </section>
     );
  },

});

1

Так, ви можете зробити це за допомогою масиву mix з рядками та елементами JSX. довідник

<MyComponent text={["This is ", <strong>not</strong>,  "working."]} />

1

Парсер від html-react-parser - хороше рішення. Ви просто повинні

  • встановіть його за допомогою npm або пряжі
  • імпорт Parser з 'html-react-parser';
  • зателефонуйте за допомогою:

    <MyComponent text=Parser("This is <strong>not</strong> working.") />

    і це добре працює.


1

Додавання до відповіді: Якщо ви маєте намір проаналізувати, і ви вже в JSX, але у вас є об'єкт з вкладеними властивостями, дуже елегантним способом є використання дужок для того, щоб змусити JSX розбирати:

const TestPage = () => (
  <Fragment>
    <MyComponent property={
    {
      html: (
        <p>This is a <a href='#'>test</a> text!</p>
      )
    }}>
    </MyComponent>
  </Fragment>
);

1

На це запитання вже було багато відповідей, але я робив щось неправильне, пов’язане з цим, і я думаю, що варто поділитися:

У мене було щось подібне:

export default function Features() {
  return (
    <Section message={<p>This is <strong>working</strong>.</p>} />
  }
}

але масаж був довший за це, тому я спробував використовувати щось подібне:

const message = () => <p>This longer message is <strong>not</strong> working.</p>;

export default function Features() {
  return (
    <Section message={message} />
  }
}

Мені знадобилося деякий час, щоб зрозуміти, що я пропускаю () у виклику функції.

Не працює

<Section message={message} />

Робочий

<Section message={message()} />

можливо, це вам допоможе, як це зробило мені!


1

Ви можете успішно використовувати фрагменти React для цього завдання. В залежності від React використовуваної версії, ви можете використовувати короткий синтаксис: <>або повний тег: <React.Fragment>. Особливо добре працює, якщо ви не хочете загортати цілий рядок у теги HTML.

<MyComponent text={<>Hello World. <u>Don't be so ruthless</u>.</>} />

0

Ми можемо зробити те ж саме таким чином.

const Child = () => {
  return (
     write your whole HTML here.
  )
}

тепер ви хочете відправити цей HTML всередині іншого компонента, ім'я якого - батьківський компонент.

Дзвінки: -

<Parent child={<child/>} >
</Parent> 

Використання дитини: -

 const Parent = (props) => {
   const { child } = props; 
   return (
       {child}
    )
}

ця робота ідеально підходить для мене.


-9

Додали html у компонентDidMount за допомогою додатка jQuery. Це повинно вирішити проблему.

 var MyComponent = React.createClass({
    render: function() {

        return (
           <div>

           </div>
        );
    },
    componentDidMount() {
        $(ReactDOM.findDOMNode(this)).append(this.props.text);
    }
});

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