แทรก HTML ด้วยข้อความตอบกลับตัวแปร (JSX)


203

ฉันกำลังสร้างบางสิ่งด้วย React ที่ฉันต้องการแทรก HTML ด้วยตัวแปร React ใน JSX มีวิธีที่จะมีตัวแปรดังนี้:

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

และใส่เข้าไปในปฏิกิริยาเช่นนั้นและทำงานได้หรือไม่

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

และมันแทรก HTML ตามที่คาดไว้หรือไม่ ฉันไม่ได้เห็นหรือได้ยินอะไรเกี่ยวกับฟังก์ชั่นตอบสนองที่สามารถทำแบบอินไลน์นี้หรือวิธีการแยกวิเคราะห์สิ่งที่จะช่วยให้การทำงาน

คำตอบ:


294

คุณสามารถใช้harmlySetInnerHTMLเช่น

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

2
มันทำงานอย่างไรถ้าคุณต้องการที่จะเพิ่มบางอย่าง<head>?
Danielle Madeley

วิธี DOM ปกติใน componentDidMount ควรใช้งานได้ฉันไม่เคยทำมาก่อน
Douglas

@DanielleMadeley คุณพยายามแทรกความคิดเห็นตามเงื่อนไข IE ใน <head> หรือไม่? ถ้าเป็นเช่นนั้นฉันได้ประสบความสำเร็จในการใช้กลอุบายที่อธิบายไว้ที่นี่: nemisj.com/conditional-ie-comments-in-react-js
Cam Jackson

3
ตรวจสอบให้แน่ใจว่าคุณผ่านวิธีการไปยังชุดอันตรายอย่างในตัว HTML และไม่ใช่แฮช ตามเอกสารนั้นมันอันตรายที่จะต้องผ่านการแฮช การอ้างอิง: facebook.github.io/react/tips/dangerously-set-inner-html.html
criticerz

1
มีวิธีโดยไม่ต้องใส่ div หรือไม่?
เพื่อน

101

โปรดทราบว่า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 ไม่ควร :) :)
Artem Bernatskyi

1
เป็นไปได้หรือไม่ที่จะแสดงเฉพาะแท็ก html แต่แท็กจากไลบรารีเช่น material ui Alert tag ฉันต้องการให้รหัสเป็นเช่นนี้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> ); }
sasha romanov

@sasharomanov, คุณได้รับคำตอบสำหรับสถานการณ์นี้หรือไม่?
Nimish goel

51

dangerlySetInnerHTMLมีข้อเสียมากมายเนื่องจากอยู่ภายในแท็ก

ฉันขอแนะนำให้คุณใช้ wrapper ปฏิกิริยาเหมือนฉันพบที่นี่ใน npm เพื่อวัตถุประสงค์นี้ html-react-parserทำหน้าที่เดียวกัน

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

ง่ายมาก :)


3
"dangerlySetInnerHTML มีข้อเสียมากมายเพราะมันอยู่ในแท็ก" คุณช่วยอธิบายเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ไหม พยายามคิดว่าความแตกต่างพื้นฐานคืออะไรระหว่าง html-react-parser และ sanHized innerHtml
dchhetri

ดูเหมือนว่า html-react-parser จะไม่ฆ่าเชื้ออินพุต - ดูคำถามที่พบบ่อย
Little Brain

28

โดยการใช้''คุณจะทำให้มันเป็นสตริง ใช้โดยไม่มีเครื่องหมายจุลภาคคว่ำมันจะทำงานได้ดี


14
ตอนแรกฉันหัวเราะแล้วก็ให้โอกาสซึ่งทำให้ฉันคิดว่า
M เมื่อ

1
โดยคำตอบที่ง่ายที่สุดโดยเฉพาะอย่างยิ่งถ้า HTML เขียนโดยคุณและมีพลวัตขึ้นอยู่กับการป้อนข้อมูลของผู้ใช้ คุณสามารถตั้งค่า var myHtml = <p> บางข้อความ </p>; และใช้งานได้
pat8719

1
นี่คือคำตอบที่ดีที่สุด ขอบคุณเพื่อน!
Andy Mercer


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>)
ล้อมรอบ

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

ที่นี่มีสองลิงค์เชื่อมโยงและlink2จาก React เอกสารซึ่งอาจจะเป็นประโยชน์

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