React - Bagaimana cara melewatkan tag HTML di props?

118

Saya ingin meneruskan teks dengan tag HTML, seperti:

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

Tetapi di dalam MyComponentmetode render, ketika saya mencetak this.props.text, itu benar-benar mencetak semuanya:

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

Apakah ada cara untuk membuat React mem-parse HTML dan membuangnya dengan benar?

ffxsam.dll
sumber
Apa fungsi render Anda yang sebenarnya?
Lucio
3
Pola tipikal adalah membuat konten Anda menjadi anak-anak dari komponen Anda <MyComponent>This is <strong>not</strong> working</MyComponent>, alih-alih memberikannya sebagai properti. Bisakah Anda memberi lebih banyak konteks tentang apa yang sebenarnya Anda coba capai?
Nick Tomlin
Pertanyaan yang hampir sama: Reactjs convert to html .
totymedli

Jawaban:

140

Anda dapat menggunakan array campuran dengan string dan elemen JSX (lihat dokumen di sini ):

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

Ada biola di sini yang menunjukkannya bekerja: http://jsfiddle.net/7s7dee6L/

Selain itu, sebagai upaya terakhir, Anda selalu memiliki kemampuan untuk memasukkan HTML mentah, tetapi berhati-hatilah karena hal itu dapat membuka Anda terhadap serangan skrip lintas situs (XSS) jika tidak membersihkan nilai properti.

matagus
sumber
10
Ini berfungsi, kecuali saya sekarang mendapatkan peringatan: Peringatan: Setiap anak dalam array atau iterator harus memiliki prop unik "kunci". Periksa metode render CTA. Itu lulus anak dari Template1. Lihat fb.me/react-warning-keys untuk informasi lebih lanjut.
ffxsam
3
Anda dapat membuat kesalahan ini hilang dengan melalui array dan menambahkan indeks sebagai kunci di MyComponent {text.map( textOrHTML, index) => <span key={index}>{textOrHTML}</span> )} Meskipun, sangat aneh bahwa kita harus melakukan ini sepenuhnya.
HussienK
5
Anda juga dapat memperbaiki peringatan dengan menempatkan key="[some unique value]"pada <strong>elemen.
Chad Johnson
Bagus, berfungsi dengan baik, saya ingin tahu bagaimana saya bisa menggunakan variabel di dalam kuat daripada string 'bukan'
Jaison
2
Untuk menghapus peringatan kunci array, sekarang juga dimungkinkan untuk melewatkan satu JSX seperti ini. <MyComponent text={<>This is <strong>not</strong> working.</>} />
Arif
111

Sebenarnya, ada banyak cara untuk melakukannya.

Anda ingin menggunakan JSX di dalam properti Anda

Anda cukup menggunakan {} agar JSX mengurai parameter. Batasan satu-satunya adalah sama untuk setiap elemen JSX: Ini harus mengembalikan hanya satu elemen root.

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

Cara terbaik yang dapat dibaca untuk melakukannya adalah dengan membuat fungsi renderMyProp yang akan mengembalikan komponen JSX (seperti fungsi render standar) dan kemudian cukup memanggil myProp = {this.renderMyProp ()}

Anda hanya ingin meneruskan HTML sebagai string

Secara default, JSX tidak mengizinkan Anda merender HTML mentah dari nilai string. Namun, ada cara untuk melakukannya:

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

Kemudian di komponen Anda, Anda dapat menggunakannya seperti itu:

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

Berhati-hatilah karena solusi ini 'dapat' terbuka pada serangan pemalsuan skrip lintas situs. Juga berhati-hatilah karena Anda hanya dapat merender HTML sederhana, tanpa tag JSX atau komponen atau hal-hal mewah lainnya.

Cara array

Sebagai reaksi, Anda bisa melewatkan larik elemen JSX. Itu berarti:

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

Saya tidak akan merekomendasikan metode ini karena:

  • Ini akan membuat peringatan (kunci hilang)
  • Itu tidak bisa dibaca
  • Ini sebenarnya bukan cara BEJ, ini lebih merupakan peretasan daripada desain yang dimaksudkan.

Cara anak-anak

Menambahkannya demi kelengkapan tetapi dalam bereaksi, Anda juga bisa mendapatkan semua anak yang ada 'di dalam' komponen Anda.

Jadi jika saya ambil kode berikut:

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

Kemudian dua div akan tersedia sebagai this.props.children di SomeComponent dan bisa dirender dengan sintaks {} standar.

Solusi ini sempurna ketika Anda hanya memiliki satu konten HTML untuk diteruskan ke Komponen Anda (Bayangkan komponen Popin yang hanya mengambil konten Popin sebagai anak-anak).

Namun, jika Anda memiliki banyak konten, Anda tidak dapat menggunakan anak-anak (atau Anda setidaknya perlu menggabungkannya dengan solusi lain di sini)

Atrakeur
sumber
1
this.props.childrens - tetapi this.props.children. Tanpa 's' reactjs.org/docs/glossary.html#propschildren
Alexiuscrow
13

Anda dapat menggunakan hazardouslySetInnerHTML

Kirimkan saja html sebagai string biasa

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

Dan render dalam kode JSX seperti ini:

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

Berhati-hatilah jika Anda merender data yang dimasukkan oleh pengguna. Anda bisa menjadi korban serangan XSS

Berikut dokumentasinya: https://facebook.github.io/react/tips/dangerously-set-inner-html.html

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

dan kemudian di komponen Anda, Anda dapat melakukan pemeriksaan prop seperti:

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

Pastikan Anda memilih hanya satu jenis prop.


sumber
6

Bagi saya Ini bekerja dengan melewatkan tag html di alat peraga anak-anak

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


var MyComponent = React.createClass({

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

Pada aplikasi react sisi klien, ada beberapa cara untuk merender prop sebagai string dengan beberapa html. Yang satu lebih aman dari yang lain ...

1 - Tentukan prop sebagai jsx (preferensi saya)

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


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

• Satu-satunya persyaratan di sini adalah bahwa file apa pun yang menghasilkan prop ini perlu menyertakan React sebagai dependency (jika Anda membuat prop's jsx dalam file helper dll).

2 - Setel innerHtml dengan berbahaya

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

• Pendekatan kedua ini tidak disarankan. Bayangkan sebuah field input yang nilai inputnya di-render sebagai sebuah prop dalam komponen ini. Seorang pengguna dapat memasukkan tag skrip dalam masukan dan komponen yang membuat masukan ini akan menjalankan kode yang berpotensi berbahaya ini. Dengan demikian, pendekatan ini berpotensi menimbulkan kerentanan pembuatan skrip lintas situs. Untuk informasi lebih lanjut, lihat dokumen resmi React

Vijay Selvan Ram
sumber
4

Setel jenis teks prop ke sembarang dan lakukan ini:

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

Contoh

Amey Parundekar
sumber
3

Anda dapat melakukannya dengan 2 cara yang saya ketahui.

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

Dan kemudian lakukan ini

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

Atau pendekatan kedua lakukan seperti ini

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

Dan kemudian lakukan ini

class MyComponent extends React.Component {
   render () {
     return (<div>{this.props.children}</div>)
   }
}
Adeel Imran
sumber
1
Saya menambahkan variabel let vhtml = "<p>Test</p>"dan menggunakannya pada prop seperti ini text={vhtml}dan itu masih ditampilkan dalam teks biasa untuk beberapa alasan.
Si8
2

@ matagus jawaban baik untuk saya, Semoga cuplikan di bawah ini membantu mereka yang ingin menggunakan variabel di dalamnya.

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

Dalam proyek saya, saya harus meneruskan cuplikan html dinamis dari variabel dan merendernya di dalam komponen. Jadi saya melakukan hal berikut.

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

objek defaultSelection diteruskan ke komponen dari .jsfile

<HtmlSnippet innerHtml={defaultSelection.innerHtml} />

Komponen HtmlSnippet

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

Contoh Plunkr

react doc untuk hazardouslySetInnerHTML

Rajkishor Sahu
sumber
1

Anda juga bisa menggunakan fungsi pada komponen untuk meneruskan jsx melalui props. Suka:

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

});
Allison
sumber
1

Ya, Anda dapat melakukannya dengan menggunakan array campuran dengan string dan elemen JSX. referensi

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

Parser dari html-react-parser adalah solusi yang bagus. Anda harus melakukannya

  • pasang dengan npm atau benang
  • import Parser dari 'html-react-parser';
  • sebut saja dengan:

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

    dan itu bekerja dengan baik.

Franck212
sumber
1

Menambah jawaban: Jika Anda berniat untuk mengurai dan Anda sudah berada di JSX tetapi memiliki objek dengan properti bersarang, cara yang sangat elegan adalah menggunakan tanda kurung untuk memaksa penguraian JSX:

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

Pertanyaan ini sudah memiliki banyak jawaban, tetapi saya telah melakukan sesuatu yang salah terkait dengan ini dan menurut saya layak untuk dibagikan:

Saya punya sesuatu seperti ini:

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

tetapi pijatannya lebih lama dari itu, jadi saya mencoba menggunakan sesuatu seperti ini:

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

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

Butuh beberapa saat bagi saya untuk menyadari bahwa saya kehilangan () dalam pemanggilan fungsi.

Tidak bekerja

<Section message={message} />

Kerja

<Section message={message()} />

mungkin ini membantu Anda, seperti yang terjadi pada saya!

Abraham Hernandez
sumber
1

Anda berhasil menggunakan fragmen React untuk tugas ini. Tergantung pada versi yang Anda gunakan Bereaksi, Anda dapat menggunakan sintaks pendek: <>atau tag penuh: <React.Fragment>. Berfungsi sangat baik jika Anda tidak ingin membungkus seluruh string dalam tag HTML.

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

Kita bisa melakukan hal yang sama sedemikian rupa.

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

sekarang Anda ingin mengirim HTML ini ke dalam komponen lain yang bernama komponen Induk.

Menelepon: -

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

Penggunaan Anak: -

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

ini bekerja sempurna untuk saya.

pushparmar
sumber
-9

Telah menambahkan html di componentDidMount menggunakan jQuery append. Ini seharusnya menyelesaikan masalah.

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

        return (
           <div>

           </div>
        );
    },
    componentDidMount() {
        $(ReactDOM.findDOMNode(this)).append(this.props.text);
    }
});
Kaushik
sumber
5
Ini tidak disetujui karena Anda tidak boleh menggunakan manipulasi DOM langsung jquery yang dikombinasikan dengan manipulasi DOM tidak langsung react, karena dapat menyebabkan browser meronta-ronta.
Allison