ตอบสนอง - วิธีส่งแท็ก HTML ในอุปกรณ์ประกอบฉาก?


118

ฉันต้องการส่งข้อความด้วยแท็ก HTML ดังนี้:

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

แต่ภายในMyComponentวิธีการเรนเดอร์ของเมื่อฉันพิมพ์ออกมาthis.props.textมันจะพิมพ์ทุกอย่างออกมาอย่างแท้จริง:

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

มีวิธีใดบ้างที่จะทำให้ React แยกวิเคราะห์ HTML และถ่ายโอนข้อมูลออกอย่างถูกต้อง


ฟังก์ชันการแสดงผลจริงของคุณคืออะไร?
Lucio

3
รูปแบบทั่วไปคือการทำให้เนื้อหาของคุณเป็นส่วนประกอบของคุณ<MyComponent>This is <strong>not</strong> working</MyComponent>แทนที่จะส่งเป็นอุปกรณ์ประกอบฉาก คุณช่วยให้บริบทเพิ่มเติมเกี่ยวกับสิ่งที่คุณพยายามทำให้สำเร็จได้หรือไม่?
Nick Tomlin

เกือบคำถามเดียวกัน: Reactjs แปลงเป็น HTML
totymedli

คำตอบ:


140

คุณสามารถใช้อาร์เรย์ผสมกับสตริงและองค์ประกอบ JSX (ดูเอกสารที่นี่ ):

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

มีซอที่แสดงว่ามันใช้งานได้: http://jsfiddle.net/7s7dee6L/

นอกจากนี้คุณยังมีความสามารถในการแทรก HTML ดิบได้เสมอแต่ต้องระวังเพราะอาจทำให้คุณสามารถโจมตีแบบ cross-site scripting (XSS) ได้หากไม่ได้ล้างค่าคุณสมบัติ


10
วิธีนี้ใช้ได้ผลยกเว้นตอนนี้ฉันได้รับคำเตือน: คำเตือน: ลูกแต่ละคนในอาร์เรย์หรือตัววนซ้ำควรมีเสา "คีย์" ที่ไม่ซ้ำกัน ตรวจสอบวิธีการแสดงผลของ CTA ส่งลูกจาก Template1 ดูfb.me/react-warning-keysสำหรับข้อมูลเพิ่มเติม
ffxsam

3
คุณสามารถทำให้ข้อผิดพลาดนี้หายไปได้โดยไปที่อาร์เรย์และเพิ่มดัชนีเป็นคีย์ใน MyComponent {text.map( textOrHTML, index) => <span key={index}>{textOrHTML}</span> )} แม้ว่ามันจะแปลกมากที่เราต้องทำสิ่งนี้ตั้งแต่แรกทั้งหมด
HussienK

5
นอกจากนี้คุณยังสามารถแก้ไขคำเตือนโดยการวางkey="[some unique value]"บน<strong>องค์ประกอบ
Chad Johnson

ดีทำงานได้ดีฉันต้องการทราบว่าฉันจะใช้ตัวแปรภายในที่แข็งแกร่งแทนสตริง 'not' ได้อย่างไร
Jaison

3
ในการลบคำเตือนคีย์อาร์เรย์ตอนนี้คุณสามารถส่ง JSX เดียวเช่นนี้ได้ <MyComponent text={<>This is <strong>not</strong> working.</>} />
Arif

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>

จากนั้นทั้งสอง div จะพร้อมใช้งานเป็น this.props.children ใน SomeComponent และสามารถแสดงผลด้วยไวยากรณ์มาตรฐาน {}

โซลูชันนี้เหมาะอย่างยิ่งเมื่อคุณมีเนื้อหา HTML เพียงรายการเดียวที่จะส่งผ่านไปยังคอมโพเนนต์ของคุณ (ลองนึกภาพส่วนประกอบของ Popin ที่ใช้เนื้อหาของ Popin เป็นลูกเท่านั้น)

อย่างไรก็ตามหากคุณมีเนื้อหาหลายรายการคุณไม่สามารถใช้ลูก ๆ ได้ (หรืออย่างน้อยคุณต้องรวมเข้ากับโซลูชันอื่นที่นี่)


1
this.props.childrens - แต่this.props.children. ไม่มีปฏิกิริยา
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

ในแอปพลิเคชันตอบกลับฝั่งไคลเอ็นต์มีสองวิธีในการแสดงผล prop เป็นสตริงที่มี html ปลอดภัยกว่าที่อื่น ...

1 - กำหนด prop เป็น jsx (ค่ากำหนดของฉัน)

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


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

•ข้อกำหนดเดียวที่นี่คือไฟล์ใดก็ตามที่สร้าง prop นี้จำเป็นต้องรวม React เป็นการอ้างอิง (ในกรณีที่คุณสร้าง jsx ของ prop ในไฟล์ตัวช่วยเป็นต้น)

2 - ตั้งค่า innerHtml อย่างอันตราย

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

คุณสามารถทำได้ 2 วิธีที่ฉันทราบ

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

ตัวอย่าง Plunkr

ทำปฏิกิริยากับ doc สำหรับ 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

Parser จาก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.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 ใน componentDidMount โดยใช้ jQuery append สิ่งนี้ควรแก้ปัญหาได้

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

        return (
           <div>

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

5
สิ่งนี้ถูกโหวตลงเนื่องจากคุณไม่ควรใช้การจัดการ DOM โดยตรงของ jquery รวมกับการจัดการ DOM ทางอ้อมของปฏิกิริยาเนื่องจากอาจนำไปสู่การบีบเบราว์เซอร์
Allison
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.