React - Sahne alanında HTML etiketleri nasıl geçirilir?


118

Metni HTML etiketleriyle iletebilmek istiyorum, örneğin:

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

Ancak MyComponentrender yönteminin içinde, yazdırdığımda this.props.text, kelimenin tam anlamıyla her şeyi yazdırıyor:

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

React'in HTML'yi ayrıştırıp düzgün bir şekilde atmasını sağlamanın bir yolu var mı?


Gerçek oluşturma işleviniz nedir?
Lucio

3
Tipik model, içeriğinizi <MyComponent>This is <strong>not</strong> working</MyComponent>sahne olarak geçirmek yerine bileşeninizin alt bileşenlerini yapmak olacaktır . Gerçekte neyi başarmaya çalıştığınıza dair daha fazla bağlam verebilir misiniz?
Nick Tomlin

Hemen hemen aynı soru: Reactj'ler html'ye dönüşür .
totymedli

Yanıtlar:


140

Sen dizeleri ve JSX elemanları (docs bkz ile karışık diziler kullanabilirsiniz burada ):

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

Burada çalıştığını gösteren bir keman var: http://jsfiddle.net/7s7dee6L/

Ayrıca, son çare olarak, her zaman ham HTML ekleme yeteneğiniz vardır, ancak dikkatli olun çünkü bu, özellik değerlerini temizlemiyorsanız sizi siteler arası komut dosyası (XSS) saldırısına açabilir.


10
Şimdi bir uyarı almam dışında bu işe yarıyor: Uyarı: Bir dizideki veya yineleyicideki her çocuk benzersiz bir "anahtar" özelliğine sahip olmalıdır. CTA'nın oluşturma yöntemini kontrol edin. Şablon1'den bir çocuk geçti. Daha fazla bilgi için fb.me/react-warning-keys bakın .
ffxsam

3
Diziden geçerek ve dizini MyComponent'e anahtar olarak ekleyerek bu hatayı ortadan kaldırabilirsiniz. {text.map( textOrHTML, index) => <span key={index}>{textOrHTML}</span> )} Yine de, ilk etapta bunu tamamen yapmak zorunda olmamız çok garip.
HussienK

5
Ayrıca koyarak uyarıyı düzeltebilirsiniz key="[some unique value]"üzerinde <strong>eleman.
Chad Johnson

Güzel, iyi çalışıyor, 'değil' dizesi yerine strong içinde bir değişkeni nasıl kullanabilirim bilmek istiyorum
Jaison

3
Dizi anahtarı uyarısını kaldırmak için artık bunun gibi tek bir JSX geçmek de mümkündür. <MyComponent text={<>This is <strong>not</strong> working.</>} />
Arif

111

Aslında bununla gitmenin birden fazla yolu var.

Sahne donanımınızın içinde JSX kullanmak istiyorsunuz

JSX'in parametreyi ayrıştırmasına neden olmak için {} kullanabilirsiniz. Tek sınırlama, her JSX öğesi ile aynıdır: Yalnızca bir kök öğe döndürmelidir.

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

Bunu yapmanın en iyi okunabilir yolu, JSX bileşenlerini döndürecek bir renderMyProp işlevi oluşturmaktır (standart oluşturma işlevi gibi) ve ardından myProp = {this.renderMyProp ()}

Bir dizge olarak yalnızca HTML'yi geçirmek istiyorsunuz

Varsayılan olarak JSX, dize değerlerinden ham HTML oluşturmanıza izin vermez. Ancak bunu yapmanın bir yolu var:

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

Ardından bileşeninizde şu şekilde kullanabilirsiniz:

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

Bu çözümün siteler arası kodlama sahteciliği saldırılarında açılabileceğine dikkat edin. Ayrıca, yalnızca basit HTML oluşturabileceğinizden, JSX etiketi veya bileşeni veya diğer süslü şeyler yapamayacağınıza dikkat edin.

Dizi yolu

React'te, bir dizi JSX öğesi iletebilirsiniz. Bunun anlamı:

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

Bu yöntemi tavsiye etmem çünkü:

  • Bir uyarı oluşturacak (eksik anahtarlar)
  • Okunabilir değil
  • Bu gerçekten JSX yolu değil, amaçlanan bir tasarımdan çok bir hack.

Çocukların yolu

Eksiksizlik uğruna ama tepki olarak, bileşeninizin 'içindeki' tüm çocukları da alabilirsiniz.

Yani aşağıdaki kodu alırsam:

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

Daha sonra iki div, SomeComponent içinde this.props.children olarak kullanılabilir ve standart {} sözdizimi ile işlenebilir.

Bu çözüm, Bileşeninize aktarılacak yalnızca bir HTML içeriğiniz olduğunda mükemmeldir (yalnızca Popin'in içeriğini alt öğe olarak alan bir Popin bileşeni düşünün).

Bununla birlikte, birden fazla içeriğiniz varsa, çocukları kullanamazsınız (veya en azından burada başka bir çözümle birleştirmeniz gerekir)


1
this.props.childrens - ama this.props.children. "S" olmadan reactjs.org/docs/glossary.html#propschildren
Alexiuscrow

13

Tehlikeli olarak kullanabilirsinSetInnerHTML

Sadece html'yi normal bir dize olarak gönderin

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

Ve JSX kodunda şu şekilde işleyin:

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

Kullanıcı tarafından girilen verileri işliyorsanız dikkatli olun. XSS saldırısının kurbanı olabilirsiniz

Belgeler şu şekildedir: https://facebook.github.io/react/tips/dangerously-set-inner-html.html


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

ve sonra bileşeninizde şu şekilde pervane kontrolü yapabilirsiniz:

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

Yalnızca bir pervane türü seçtiğinizden emin olun.



6

Benim için, sahne çocuklarında html etiketi geçerek çalıştı

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


var MyComponent = React.createClass({

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

6

İstemci tarafındaki bir tepki uygulamasında, bir pervaneyi html ile dizge olarak oluşturmanın birkaç yolu vardır. Biri diğerinden daha güvenli ...

1 - pervaneyi jsx olarak tanımla (tercihim)

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


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

• Buradaki tek gereksinim, bu propu oluşturan dosya ne olursa olsun, bağımlılık olarak React'i içermesi gerektiğidir (bir yardımcı dosyada prop jsx'ini oluşturuyorsanız vb.).

2 - InternalHtml'yi tehlikeli bir şekilde ayarlayın

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

• Bu ikinci yaklaşım tavsiye edilmez. Bu bileşende girdi değeri bir prop olarak işlenen bir girdi alanı hayal edin. Bir kullanıcı girişe bir komut dosyası etiketi girebilir ve bu girişi oluşturan bileşen, bu potansiyel olarak kötü amaçlı kodu yürütür. Bu nedenle, bu yaklaşım siteler arası komut dosyası çalıştırma güvenlik açıkları oluşturma potansiyeline sahiptir. Daha fazla bilgi için resmi React belgelerine bakın


4

Metin pervanesi türünü herhangi birine ayarlayın ve bunu yapın:

<MyComponent text={
    <React.Fragment>
        <div> Hello, World!</div>
    </React.Fragment>
    } 
/>

Misal


3

Benim bildiğim 2 şekilde yapabilirsiniz.

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

Ve sonra bunu yap

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

Veya ikinci yaklaşım bunu böyle yap

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

Ve sonra bunu yap

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

1
Bir değişken ekledim let vhtml = "<p>Test</p>"ve bu şekilde pervane üzerinde kullandım text={vhtml}ve yine de nedense düz metin olarak görüntüleniyor.
Si8

2

@matagus cevabı benim için iyi, umarım snippet'in altında değişken kullanmak isteyenlere yardımcı olur.

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

1

Projemde değişkenden dinamik html parçacığı geçirip bileşen içinde render etmem gerekiyordu. Ben de aşağıdakileri yaptım.

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

defaultSelection nesnesi, .jsdosyadan bileşene aktarılır

<HtmlSnippet innerHtml={defaultSelection.innerHtml} />

HtmlSnippet bileşeni

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

Plunkr örneği

doc için hazardouslySetInnerHTML için tepki verin


1

Ayrıca jsx boyunca props'a geçmek için bileşen üzerinde bir işlev kullanabilirsiniz. sevmek:

 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

Evet, dizeler ve JSX öğeleriyle karışık dizi kullanarak bunu yapabilirsiniz. referans

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

1

Den Ayrıştırıcı html reaksiyona-ayrıştırıcı iyi bir çözümdür. Sadece yapmalısın

  • npm veya iplik ile kurun
  • 'html-react-parser'dan ayrıştırıcıyı içe aktarın;
  • şununla ara:

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

    ve iyi çalışıyor.


1

Yanıta ekleme: Ayrıştırmayı planlıyorsanız ve zaten JSX içindeyseniz ancak iç içe özelliklere sahip bir nesneye sahipseniz, JSX ayrıştırmasını zorlamak için çok zarif bir yol parantez kullanmaktır:

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

1

Bu sorunun zaten birçok cevabı var, ancak bununla ilgili yanlış bir şey yapıyordum ve paylaşmaya değer olduğunu düşünüyorum:

Bende bunun gibi bir şey vardı:

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

ama masaj bundan daha uzundu, bu yüzden şöyle bir şey kullanmayı denedim:

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

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

İşlev çağrısındaki () işaretini kaçırdığımı anlamam biraz zaman aldı.

Çalışmıyor

<Section message={message} />

Çalışma

<Section message={message()} />

bana yaptığı gibi belki bu sana yardımcı olur!


1

Bu görev için React parçalarını başarıyla kullanabilirsiniz . Kullandığınız React sürümüne bağlı olarak, kısa sözdizimi: <>veya tam etiket: kullanabilirsiniz <React.Fragment>. Tüm dizeyi HTML etiketlerine sarmak istemiyorsanız özellikle iyi çalışır.

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

0

Aynı şeyi bu şekilde yapabiliriz.

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

şimdi bu HTML'yi, adı Üst bileşen olan başka bir bileşenin içine göndermek istiyorsunuz.

Arıyor: -

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

Çocuk Kullanımı: -

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

bu benim için mükemmel çalışıyor.


-9

JQuery ekini kullanarak componentDidMount'a html'yi eklediniz. Bu sorunu çözmelidir.

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

        return (
           <div>

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

5
Bu, olumsuz oylanmıştır çünkü jquery'nin doğrudan DOM manipülasyonunu react'in dolaylı DOM manipülasyonuyla birlikte kullanmamanız gerekir, çünkü bu, tarayıcının yıkılmasına neden olabilir.
Allison
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.