Reagieren - Wie werden HTML-Tags in Requisiten übergeben?

118

Ich möchte in der Lage sein, Text mit HTML-Tags zu übergeben, wie folgt:

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

Aber innerhalb der Rendermethode druckt es MyComponentbeim Ausdrucken this.props.textbuchstäblich alles aus:

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

Gibt es eine Möglichkeit, React dazu zu bringen, HTML zu analysieren und ordnungsgemäß auszugeben?

ffxsam
quelle
Was ist Ihre eigentliche Renderfunktion?
Lucio
3
Das typische Muster wäre, Ihre Inhalte zu untergeordneten Elementen Ihrer Komponente zu machen <MyComponent>This is <strong>not</strong> working</MyComponent>, anstatt sie als Requisiten zu übergeben. Könnten Sie mehr Kontext zu dem geben, was Sie tatsächlich erreichen wollen?
Nick Tomlin
Fast die gleiche Frage: Reactjs konvertieren in HTML .
Totymedli

Antworten:

140

Sie können gemischte Arrays mit Zeichenfolgen und JSX-Elementen verwenden (siehe die Dokumente hier ):

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

Hier gibt es eine Geige, die zeigt, dass sie funktioniert: http://jsfiddle.net/7s7dee6L/

Als letztes Mittel haben Sie immer die Möglichkeit, unformatiertes HTML einzufügen. Seien Sie jedoch vorsichtig, da dies Sie für einen XSS-Angriff (Cross-Site Scripting) öffnen kann, wenn die Eigenschaftswerte nicht bereinigt werden.

Matagus
quelle
10
Dies funktioniert, außer dass ich jetzt eine Warnung erhalte: Warnung: Jedes Kind in einem Array oder Iterator sollte eine eindeutige "Schlüssel" -Stütze haben. Überprüfen Sie die Rendermethode von CTA. Es wurde ein Kind aus Template1 übergeben. Weitere Informationen finden Sie unter fb.me/react-warning-keys .
ffxsam
3
Sie können diesen Fehler beheben {text.map( textOrHTML, index) => <span key={index}>{textOrHTML}</span> )} , indem Sie das Array durchgehen und den Index als Schlüssel in MyComponent hinzufügen . Es ist jedoch so seltsam, dass wir dies zunächst vollständig tun müssen.
HussienK
5
Sie können die Warnung auch beheben, indem Sie key="[some unique value]"das <strong>Element aufsetzen.
Chad Johnson
Schön, funktioniert gut, ich würde gerne wissen, wie ich eine Variable in strong anstelle von string 'not' verwenden könnte
Jaison
2
Um die Array-Schlüsselwarnung zu entfernen, ist es jetzt auch möglich, eine einzelne JSX wie diese zu übergeben. <MyComponent text={<>This is <strong>not</strong> working.</>} />
Arif
111

Tatsächlich gibt es dafür mehrere Möglichkeiten.

Sie möchten JSX in Ihren Requisiten verwenden

Sie können einfach {} verwenden, um JSX zu veranlassen, den Parameter zu analysieren. Die einzige Einschränkung ist dieselbe wie für jedes JSX-Element: Es darf nur ein Stammelement zurückgegeben werden.

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

Der am besten lesbare Weg, dies zu tun, besteht darin, eine Funktion renderMyProp zu erstellen, die JSX-Komponenten zurückgibt (genau wie die Standard-Renderfunktion), und dann einfach myProp = {this.renderMyProp ()} aufzurufen.

Sie möchten nur HTML als Zeichenfolge übergeben

Standardmäßig können Sie in JSX kein unformatiertes HTML aus Zeichenfolgenwerten rendern. Es gibt jedoch eine Möglichkeit, dies zu erreichen:

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

Dann können Sie es in Ihrer Komponente folgendermaßen verwenden:

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

Beachten Sie, dass diese Lösung bei Cross-Site-Scripting-Fälschungsangriffen geöffnet werden kann. Beachten Sie auch, dass Sie nur einfaches HTML, kein JSX-Tag, keine JSX-Komponente oder andere ausgefallene Dinge rendern können.

Der Array-Weg

In Reaktion können Sie ein Array von JSX-Elementen übergeben. Das bedeutet:

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

Ich würde diese Methode nicht empfehlen, weil:

  • Es wird eine Warnung erstellt (fehlende Schlüssel)
  • Es ist nicht lesbar
  • Es ist nicht wirklich die JSX-Methode, es ist eher ein Hack als ein beabsichtigtes Design.

Der Kinderweg

Wenn Sie es der Vollständigkeit halber hinzufügen, aber reagieren, können Sie auch alle Kinder erhalten, die sich in Ihrer Komponente befinden.

Also, wenn ich den folgenden Code nehme:

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

Dann sind die beiden Divs als this.props.children in SomeComponent verfügbar und können mit der Standardsyntax {} gerendert werden.

Diese Lösung ist perfekt, wenn Sie nur einen HTML-Inhalt an Ihre Komponente übergeben müssen (Stellen Sie sich eine Popin-Komponente vor, die den Inhalt des Popins nur als untergeordnete Elemente verwendet).

Wenn Sie jedoch mehrere Inhalte haben, können Sie keine untergeordneten Inhalte verwenden (oder Sie müssen diese hier zumindest mit einer anderen Lösung kombinieren).

Atrakeur
quelle
1
this.props.childrens - aber this.props.children. Ohne 's' reactjs.org/docs/glossary.html#propschildren
Alexiuscrow
13

Sie können gefährlichSetInnerHTML verwenden

Senden Sie einfach das HTML als normale Zeichenfolge

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

Und rendern Sie im JSX-Code wie folgt:

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

Seien Sie vorsichtig, wenn Sie vom Benutzer eingegebene Daten rendern. Sie können Opfer eines XSS-Angriffs werden

Hier ist die Dokumentation: https://facebook.github.io/react/tips/dangerously-set-inner-html.html

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

und dann können Sie in Ihrer Komponente Requisitenprüfungen wie folgt durchführen:

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

Stellen Sie sicher, dass Sie nur einen Requisitentyp auswählen.


quelle
6

Für mich hat es funktioniert, indem ich HTML-Tags in Requisiten-Kindern übergeben habe

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


var MyComponent = React.createClass({

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

In einer clientseitigen Reaktionsanwendung gibt es verschiedene Möglichkeiten, eine Requisite als Zeichenfolge mit etwas HTML zu rendern. Einer sicherer als der andere ...

1 - Definiere die Requisite als jsx (meine Präferenz)

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


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

• Die einzige Voraussetzung hierfür ist, dass jede Datei, die diese Requisite generiert, React als Abhängigkeit enthält (falls Sie die jsx der Requisite in einer Hilfsdatei usw. generieren).

2 - Stellen Sie das innere HTML gefährlich ein

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

• Von diesem zweiten Ansatz wird abgeraten. Stellen Sie sich ein Eingabefeld vor, dessen Eingabewert in dieser Komponente als Requisite gerendert wird. Ein Benutzer könnte ein Skript-Tag in die Eingabe eingeben, und die Komponente, die diese Eingabe rendert, würde diesen potenziell schädlichen Code ausführen. Daher kann dieser Ansatz zu Sicherheitslücken bei Cross-Site-Scripting führen. Weitere Informationen finden Sie in den offiziellen React-Dokumenten

Vijay Selvan Ram
quelle
4

Setzen Sie den Text-Requisitentyp auf einen beliebigen Wert und gehen Sie folgendermaßen vor:

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

Beispiel

Amey Parundekar
quelle
3

Sie können es auf zwei Arten tun, die mir bekannt sind.

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

Und dann mach das

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

Oder machen Sie es beim zweiten Ansatz so

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

Und dann mach das

class MyComponent extends React.Component {
   render () {
     return (<div>{this.props.children}</div>)
   }
}
Adeel Imran
quelle
1
Ich habe eine Variable hinzugefügt let vhtml = "<p>Test</p>"und sie für die Requisite wie diese verwendet text={vhtml}und sie aus irgendeinem Grund immer noch im Klartext gerendert.
Si8
2

@matagus Antwort ist in Ordnung für mich, Hoffnung unter Snippet wird denen geholfen, die eine Variable im Inneren verwenden möchten.

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

In meinem Projekt musste ich ein dynamisches HTML-Snippet von einer Variablen übergeben und es innerhalb der Komponente rendern. Also habe ich folgendes gemacht.

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

Das defaultSelection- Objekt wird aus der .jsDatei an die Komponente übergeben

<HtmlSnippet innerHtml={defaultSelection.innerHtml} />

HtmlSnippet- Komponente

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

Plunkr Beispiel

Reagieren Sie doc auf gefährlich SetInnerHTML

Rajkishor Sahu
quelle
1

Sie können auch eine Funktion für die Komponente verwenden, um jsx an Requisiten weiterzuleiten. mögen:

 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
quelle
1

Ja, Sie können dies tun, indem Sie ein Mix-Array mit Zeichenfolgen und JSX-Elementen verwenden. Referenz

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

Parser von HTML-React-Parser ist eine gute Lösung. Du musst nur

  • Installieren Sie es mit npm oder Garn
  • Parser aus 'html-react-parser' importieren;
  • Nennen Sie es mit:

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

    und es funktioniert gut.

Franck212
quelle
1

Hinzufügen zur Antwort: Wenn Sie analysieren möchten und sich bereits in JSX befinden, aber ein Objekt mit verschachtelten Eigenschaften haben, können Sie auf elegante Weise Klammern verwenden, um das JSX-Parsen zu erzwingen:

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

Diese Frage hat bereits viele Antworten, aber ich hatte etwas falsch gemacht, und ich denke, es lohnt sich, sie zu teilen:

Ich hatte so etwas:

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

Aber die Massage war länger als das, also habe ich versucht, so etwas zu verwenden:

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

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

Es dauerte eine Weile, bis mir klar wurde, dass mir das () im Funktionsaufruf fehlte.

Funktioniert nicht

<Section message={message} />

Arbeiten

<Section message={message()} />

Vielleicht hilft dir das, genau wie mir!

Abraham Hernandez
quelle
1

Sie können React-Fragmente erfolgreich für diese Aufgabe verwenden. Abhängig von der von Ihnen verwendeten React-Version können Sie eine kurze Syntax verwenden: <>oder das vollständige Tag : <React.Fragment>. Funktioniert besonders gut, wenn Sie nicht die gesamte Zeichenfolge in HTML-Tags einschließen möchten.

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

Habe das HTML in componentDidMount mit jQuery append angehängt. Dies sollte das Problem lösen.

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

        return (
           <div>

           </div>
        );
    },
    componentDidMount() {
        $(ReactDOM.findDOMNode(this)).append(this.props.text);
    }
});
Kaushik
quelle
5
Dies wird abgelehnt, da Sie die direkte DOM-Manipulation von jquery nicht mit der indirekten DOM-Manipulation von reag kombinieren sollten, da dies zu Browser-Thrashing führen kann.
Allison