रिएक्ट घटक में वास्तविक HTML के रूप में HTML स्ट्रिंग को रेंडर करें


159

यहाँ मैंने क्या कोशिश की और यह कैसे गलत हो जाता है।

यह काम:

<div dangerouslySetInnerHTML={{ __html: "<h1>Hi there!</h1>" }} />

यह नहीं है:

<div dangerouslySetInnerHTML={{ __html: this.props.match.description }} />

विवरण संपत्ति HTML सामग्री का सिर्फ एक सामान्य स्ट्रिंग है। हालांकि यह एक स्ट्रिंग के रूप में प्रस्तुत किया गया है, किसी कारण से HTML के रूप में नहीं।

यहाँ छवि विवरण दर्ज करें

कोई सुझाव?

जवाबों:


50

जाँच करें कि क्या आप जिस पाठ को नोड में जोड़ने की कोशिश कर रहे हैं वह इस तरह से बच नहीं रहा है:

var prop = {
    match: {
        description: '&lt;h1&gt;Hi there!&lt;/h1&gt;'
    }
};

इसके अलावा:

var prop = {
    match: {
        description: '<h1>Hi there!</h1>'
    }
};

यदि बच गया है तो आपको इसे अपने सर्वर-साइड से परिवर्तित करना चाहिए।

नोड पाठ है क्योंकि बच गया है

नोड पाठ है क्योंकि बच गया है

नोड डोम नोड है क्योंकि बच नहीं है

नोड डोम नोड है क्योंकि बच नहीं है


3
यह मुद्दा था। वर्णन स्ट्रिंग HTML से बच गई थी। मैंने इसे अनसुना कर दिया और अब यह ठीक काम करता है।
सर्जियो तापिया

4
कृपया प्रतिक्रिया v16 के dangerouslySetInnerHTMLबजाय इसके उपयोग Fragmentसे बचें । चेक अगले जवाब @ ब्रैड-एडम्स द्वारा
कुणाल पारेख

2
@KunalParekh उल्लेख की सराहना करते हैं, लेकिन वे अलग चीजें हैं। मेरा उत्तर केवल मान्य है यदि html आपके ऐप के भीतर स्थित है (जिसका अर्थ है कि यह वास्तव में JSX है)। किसी बाहरी स्रोत से HTML को jsx में पार्स करने के लिए आपको एक और समाधान की आवश्यकता होगी।
ब्रैड एडम्स

113

क्या this.props.match.descriptionएक स्ट्रिंग या एक वस्तु है? यदि यह एक तार है, तो इसे ठीक HTML में परिवर्तित किया जाना चाहिए। उदाहरण:

class App extends React.Component {

constructor() {
    super();
    this.state = {
      description: '<h1 style="color:red;">something</h1>'
    }
  }

  render() {
    return (
      <div dangerouslySetInnerHTML={{ __html: this.state.description }} />
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));

परिणाम: http://codepen.io/ilanus/pen/QKgoLA?editors=1011

लेकिन अगर description: <h1 style="color:red;">something</h1>उद्धरण के बिना ''आप प्राप्त करने जा रहे हैं:

Object {
$$typeof: [object Symbol] {},
  _owner: null,
  key: null,
  props: Object {
    children: "something",
    style: "color:red;"
  },
  ref: null,
  type: "h1"
}

यदि यह एक स्ट्रिंग है और आप किसी भी HTML मार्कअप को नहीं देखते हैं तो मुझे केवल एक समस्या दिखाई देती है गलत मार्कअप ..

अपडेट करें

यदि आप HTMLEntcoins के साथ काम कर रहे हैं। आपको उन्हें भेजने से पहले उन्हें डीकोड करने की आवश्यकता हैdangerouslySetInnerHTML इसलिए उन्होंने इसे खतरनाक कहा :)

काम करने का उदाहरण:

class App extends React.Component {

  constructor() {
    super();
    this.state = {
      description: '&lt;p&gt;&lt;strong&gt;Our Opportunity:&lt;/strong&gt;&lt;/p&gt;'
    }
  }

   htmlDecode(input){
    var e = document.createElement('div');
    e.innerHTML = input;
    return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
  }

  render() {
    return (
      <div dangerouslySetInnerHTML={{ __html: this.htmlDecode(this.state.description) }} />
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));

this.props.match.descriptionएक स्ट्रिंग है, एक वस्तु नहीं है। गलत मार्कअप का क्या मतलब है? क्या आपका मतलब है अस्पष्ट टैग? प्रतिक्रिया बस इसे प्रस्तुत करना चाहिए नहीं?
सर्जियो तापिया

क्या आप यहाँ सांत्वना दे सकते हैं ।log (यह। Props.match.description);
इलनस सिप

एक उदाहरण:&lt;p&gt;&lt;strong&gt;Our Opportunity:&lt;/strong&gt;&lt;/p&gt;
सर्जियो तापिया

इस स्थिति में आपको या तो .innerHTML का उपयोग करना होगा या HTMLEntities को डीकोड करना होगा।
इलानुस २us ’

टैग के साथ कई लाइनें या HTML कोड लौटाएं: HTMLDecode (इनपुट) फ़ंक्शन {var e = document.createElement ('div'); e.innerHTML = इनपुट; var returnString = ''; for (index = 0; index <e.childNodes.length; index ++) {// सिर्फ एक स्ट्रिंग का मामला (e.childNodes [index] .nodeValue)) {returnString + = e.childNode [index] .nodeValue; } // का मामला यदि HTML (e.childNodes [index] .outerHTML) {returnString + = e.childNodes [index] .outerHTML; }} वापसी returnString; }
क्रिस एडम्स

58

मैं 'प्रतिक्रिया-html- पार्सर' का उपयोग करता हूं

yarn add react-html-parser
import ReactHtmlParser from 'react-html-parser'; 

<div> { ReactHtmlParser (html_string) } </div>

स्रोत Npmjs.com पर

अधिक दृश्यता के लिए @ okram की टिप्पणी को उठाना:

इसके github विवरण से: HTML को सीधे प्रतिक्रिया घटकों में खतरनाक तरीके से परिवर्तित करता है, ताकि npmjs.com से खतरनाक तरीके से SETInnerHTML का उपयोग करने की आवश्यकता से बचा जा सके। HTML स्ट्रिंग्स को प्रतिक्रिया घटकों में परिवर्तित करने के लिए एक उपयोगिता। खतरनाक तरीके से उपयोग किए जाने से बचा जाता है InnerHTML और मानक HTML तत्वों, विशेषताओं और इनलाइन शैलियों को उनके प्रतिक्रिया समकक्षों में रूपांतरित करता है।


11
क्या यह लाइब्रेरी बैकग्राउंड में "खतरनाक तरीके से InnerHTML" का उपयोग करती है?
उमर

1
इसके github विवरण से: Converts HTML strings directly into React components avoiding the need to use dangerouslySetInnerHTMLnpmjs.com सेA utility for converting HTML strings into React components. Avoids the use of dangerouslySetInnerHTML and converts standard HTML elements, attributes and inline styles into their React equivalents.
okram

14

यदि आपका नियंत्रण है कि html युक्त स्ट्रिंग कहां से आ रही है (यानी आपके ऐप में कहीं है), तो आप नए <Fragment>API से लाभ उठा सकते हैं , जैसे कुछ:

import React, {Fragment} from 'react'

const stringsSomeWithHtml = {
  testOne: (
    <Fragment>
      Some text <strong>wrapped with strong</strong>
    </Fragment>
  ),
  testTwo: `This is just a plain string, but it'll print fine too`,
}

...

render() {
  return <div>{stringsSomeWithHtml[prop.key]}</div>
}

11
आपके उदाहरण में html युक्त कोई स्ट्रिंग नहीं है। यह या तो jx या सादे स्ट्रिंग है।
मर्कवॉन

3
ठीक है, हाँ, तकनीकी रूप से आप सही @mrkvon हैं, हालांकि जैसा कि मैंने उल्लेख किया है, यह समाधान केवल तभी मान्य है जब "html" / jsx ऐसा कुछ है जिस पर आपका नियंत्रण है। उदाहरण के लिए, एपीआई के माध्यम से प्रदान किए गए कुछ कच्चे HTML को रेंडर करने के लिए नहीं। Fragmentएपीआई से पहले यह मेरे लिए हमेशा एक दर्द था, इसके लिए अतिरिक्त spanआवरण की आवश्यकता होती है जो कभी-कभी फ्लेक्स लेआउट के साथ गड़बड़ कर देगा। जब मैं इस सवाल का एक संभव समाधान की तलाश पर ठोकर खाई मैंने सोचा कि मैं हिस्सा था कैसे मैं चारों ओर बातें मिला है।
ब्रैड एडम्स

2
धन्यवाद! यह एकमात्र समाधान था जिसने मेरे मामले में काम किया। इसके अलावा, इस उत्तर पर mrkvon की टिप्पणी का जवाब देना: इस उत्तर में वास्तव में html Some text <strong>wrapped with strong</strong>शामिल है अर्थात html टैग शामिल है strong
बिनीता भारती

@BinitaBharati लेकिन यह एक तार नहीं है। यदि आपको API से स्ट्रिंग मिलती है जैसे "<p> यह एक स्ट्रिंग है </ p>" (या बस एक स्ट्रिंग को एक चर में संग्रहीत करता है), जब आप इस स्ट्रिंग को <Fragment> में डालते हैं, तो आउटपुट में अभी भी शामिल होगा < p> टैग।
मुचादेकल

1
@BradAdams। हालांकि अच्छी चाल। मैं ऐसे उदाहरण देख सकता हूं जहां यह काम हो जाता है।
मुचादिकाल


5

dangerouslySetInnerHTML

खतरनाक डोम ब्राउज़र में आंतरिक HTML का उपयोग करने के लिए React की प्रतिक्रिया रिएक्ट का प्रतिस्थापन है। सामान्य तौर पर, HTML को कोड से सेट करना जोखिम भरा होता है क्योंकि यह अनजाने में आपके उपयोगकर्ताओं को क्रॉस-साइट स्क्रिप्टिंग (XSS) हमले के लिए उजागर करता है। तो, आप HTML को सीधे React से सेट कर सकते हैं, लेकिन आपको खतरनाक तरीके से टाइप करना होगा HTML में और किसी ऑब्जेक्ट को __html कुंजी के साथ पास करना, खुद को याद दिलाने के लिए कि यह खतरनाक है। उदाहरण के लिए:

function createMarkup() {
  return {__html: 'First &middot; Second'};
}

function MyComponent() {
  return <div dangerouslySetInnerHTML={createMarkup()} />;
}

3

मैं एक रीफ़र करने के लिए एक साथ भीतर HTML का उपयोग करता हूं:

import React, { useRef, useEffect, useState } from 'react';

export default function Sample() {
  const spanRef = useRef<HTMLSpanElement>(null);
  const [someHTML,] = useState("some <b>bold</b>");

  useEffect(() => {
    if (spanRef.current) {
      spanRef.current.innerHTML = someHTML;
    }
  }, [spanRef.current, someHTML]);

  return <div>
    my custom text follows<br />
    <span ref={spanRef} />
  </div>
}

मुझे यह पसंद है, जब आपके पास उस लक्जरी नहीं है, तो अतिरिक्त पुस्तकालयों या सर्वर-साइड पर निर्भरता की आवश्यकता नहीं है। आपके द्वारा प्रेरित, लेकिन एक कक्षा घटक में मैंने componentDidMount() { this.message.current.innerHTML = this.state.selectedMessage.body; }शरीर किया मेरे लिए बचा हुआ HTML है।
वेबहाउंड


1

मुझे npm buildसाथ काम करने को नहीं मिलाreact-html-parser । हालाँकि, मेरे मामले में, मैं https://reactjs.org/docs/fragments.html का सफलतापूर्वक उपयोग करने में सक्षम था । मुझे कुछ html यूनिकोड वर्ण दिखाने की आवश्यकता थी, लेकिन उन्हें सीधे JSX में एम्बेड नहीं किया जाना चाहिए। JSX के भीतर, इसे कंपोनेंट की स्थिति से चुना जाना था। घटक कोड स्निपेट नीचे दिया गया है:

constructor() 
{
this.state = {
      rankMap : {"5" : <Fragment>&#9733; &#9733; &#9733; &#9733; &#9733;</Fragment> , 
                 "4" : <Fragment>&#9733; &#9733; &#9733; &#9733; &#9734;</Fragment>, 
                 "3" : <Fragment>&#9733; &#9733; &#9733; &#9734; &#9734;</Fragment> , 
                 "2" : <Fragment>&#9733; &#9733; &#9734; &#9734; &#9734;</Fragment>, 
                 "1" : <Fragment>&#9733; &#9734; &#9734; &#9734; &#9734;</Fragment>}
                };
}

render() 
{
       return (<div class="card-footer">
                    <small class="text-muted">{ this.state.rankMap["5"] }</small>
               </div>);
}


-2

यदि आपके पास {this.props.match.description} का नियंत्रण है और यदि आप JSX का उपयोग कर रहे हैं। मैं "खतरनाक तरीके से InnerHTML" का उपयोग नहीं करने की सलाह दूंगा।

// In JSX, you can define a html object rather than a string to contain raw HTML
let description = <h1>Hi there!</h1>;

// Here is how you print
return (
    {description}
);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.