React - Jak przekazać tagi HTML w rekwizytach?

118

Chcę móc przekazywać tekst za pomocą tagów HTML, na przykład:

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

Ale wewnątrz MyComponentmetody renderowania, kiedy drukuję this.props.text, to dosłownie wypisuje wszystko:

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

Czy jest jakiś sposób, aby React przeanalizował HTML i poprawnie go zrzucił?

ffxsam
źródło
Jaka jest twoja rzeczywista funkcja renderowania?
Lucio,
3
Typowym wzorcem byłoby uczynienie treści podrzędnych z komponentu <MyComponent>This is <strong>not</strong> working</MyComponent>, zamiast przekazywania ich jako rekwizytów. Czy mógłbyś podać więcej kontekstu na temat tego, co faktycznie próbujesz osiągnąć?
Nick Tomlin
Prawie to samo pytanie: Reactjs konwertuje do html .
totymedli

Odpowiedzi:

140

Możesz używać tablic mieszanych z ciągami znaków i elementami JSX (zobacz dokumentację tutaj ):

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

Jest tu skrzypce, które pokazuje, że działa: http://jsfiddle.net/7s7dee6L/

Ponadto w ostateczności zawsze masz możliwość wstawienia surowego kodu HTML, ale bądź ostrożny, ponieważ może to otworzyć cię na atak cross-site scripting (XSS), jeśli nie oczyszczasz wartości właściwości.

matagus
źródło
10
To działa, z wyjątkiem tego, że teraz otrzymuję ostrzeżenie: Ostrzeżenie: Każde dziecko w tablicy lub iteratorze powinno mieć unikalną właściwość „key”. Sprawdź metodę renderowania CTA. Przekazano mu dziecko z Template1. Więcej informacji można znaleźć na stronie fb.me/react-warning-keys .
ffxsam
3
Możesz usunąć ten błąd, przeglądając tablicę i dodając indeks jako klucz w MyComponent. {text.map( textOrHTML, index) => <span key={index}>{textOrHTML}</span> )} Chociaż jest to tak dziwne, że musimy to zrobić w całości.
HussienK,
5
Można również ustalić ostrzeżenie poprzez umieszczenie key="[some unique value]"na <strong>elemencie.
Chad Johnson
Fajnie, działa dobrze, chciałbym wiedzieć, jak mogę użyć zmiennej wewnątrz silnej zamiast ciągu
`
2
Aby usunąć ostrzeżenie o kluczu tablicy, można teraz również przekazać pojedynczy JSX w ten sposób. <MyComponent text={<>This is <strong>not</strong> working.</>} />
Arif
111

W rzeczywistości jest na to wiele sposobów.

Chcesz użyć JSX w swoich rekwizytach

Możesz po prostu użyć {}, aby JSX przeanalizował parametr. Jedyne ograniczenie jest takie samo jak w przypadku każdego elementu JSX: musi zwracać tylko jeden element główny.

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

Najlepszym czytelnym sposobem na to jest utworzenie funkcji renderMyProp, która zwróci komponenty JSX (tak jak standardowa funkcja renderująca), a następnie po prostu wywołaj myProp = {this.renderMyProp ()}

Chcesz przekazać tylko HTML jako ciąg

Domyślnie JSX nie pozwala na renderowanie surowego kodu HTML z wartości ciągów. Jest jednak sposób, aby to zrobić:

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

Następnie w swoim komponencie możesz go użyć w ten sposób:

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

Należy pamiętać, że to rozwiązanie „może” otwierać się w przypadku ataków fałszerstw opartych na skryptach między witrynami. Uważaj również, że możesz renderować tylko prosty HTML, bez znacznika lub komponentu JSX ani innych fantazyjnych rzeczy.

Sposób tablicy

W reakcji możesz przekazać tablicę elementów JSX. To znaczy:

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

Nie polecałbym tej metody, ponieważ:

  • Stworzy ostrzeżenie (brakujące klucze)
  • To jest nieczytelne
  • To naprawdę nie jest sposób JSX, to bardziej hack niż zamierzony projekt.

Droga dzieci

Dodając to ze względu na kompletność, ale w odpowiedzi możesz również uzyskać wszystkie dzieci, które są „wewnątrz” twojego komponentu.

Więc jeśli wezmę następujący kod:

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

Wtedy te dwa elementy div będą dostępne jako this.props.children w SomeComponent i mogą być renderowane przy użyciu standardowej składni {}.

To rozwiązanie jest idealne, gdy masz tylko jedną treść HTML do przekazania do swojego komponentu (wyobraź sobie komponent Popin, który przyjmuje tylko zawartość Popina jako dzieci).

Jeśli jednak masz wiele treści, nie możesz używać dzieci (lub musisz przynajmniej połączyć to z innym rozwiązaniem tutaj)

Atrakeur
źródło
1
this.props.childrens - ale this.props.children. Bez 's' awarejs.org/docs/glossary.html#propschildren
Alexiuscrow
13

Możesz użyć niebezpiecznie SetInnerHTML

Po prostu wyślij kod HTML jako zwykły ciąg znaków

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

I renderuj w kodzie JSX w ten sposób:

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

Uważaj tylko, jeśli renderujesz dane wprowadzone przez użytkownika. Możesz być ofiarą ataku XSS

Oto dokumentacja: https://facebook.github.io/react/tips/dangerously-set-inner-html.html

hecontreraso
źródło
7
<MyComponent text={<span>This is <strong>not</strong> working.</span>} />

a następnie w swoim komponencie możesz sprawdzić właściwości w następujący sposób:

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

Upewnij się, że wybrałeś tylko jeden typ rekwizytu.


źródło
6

U mnie to działało, przekazując tag HTML w rekwizytach dzieci

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


var MyComponent = React.createClass({

   render: function() {
    return (
      <div>this.props.children</div>
    );
   },
Shashi3456643
źródło
6

W aplikacji reagującej po stronie klienta istnieje kilka sposobów renderowania właściwości jako ciągu znaków z pewnym kodem HTML. Jeden bezpieczniejszy niż drugi ...

1 - Zdefiniuj prop jako jsx (moje preferencje)

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


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

• Jedynym wymaganiem jest tutaj to, że każdy plik, który generuje tę właściwość, musi zawierać zależność React (w przypadku, gdy generujesz plik jsx właściwości w pliku pomocniczym itp.).

2 - Niebezpiecznie ustaw plik 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>
}

• To drugie podejście jest odradzane. Wyobraź sobie pole wejściowe, którego wartość wejściowa jest renderowana jako właściwość w tym komponencie. Użytkownik mógłby wprowadzić znacznik skryptu w danych wejściowych, a komponent, który renderuje te dane wejściowe, wykonałby ten potencjalnie złośliwy kod. W związku z tym takie podejście może potencjalnie wprowadzić luki w zabezpieczeniach skryptów między witrynami. Aby uzyskać więcej informacji, zapoznaj się z oficjalną dokumentacją React

Vijay Selvan Ram
źródło
4

Ustaw typ właściwości tekstu na dowolny i wykonaj następujące czynności:

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

Przykład

Amey Parundekar
źródło
3

Możesz to zrobić na dwa znane mi sposoby.

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

A potem zrób to

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

Lub drugie podejście zrób to w ten sposób

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

A potem zrób to

class MyComponent extends React.Component {
   render () {
     return (<div>{this.props.children}</div>)
   }
}
Adeel Imran
źródło
1
Dodałem zmienną let vhtml = "<p>Test</p>"i użyłem jej w rekwizycie w ten text={vhtml}sposób, ale z jakiegoś powodu nadal jest renderowana jako zwykły tekst.
Si8,
2

@matagus odpowiedź jest dla mnie w porządku, mam nadzieję, że poniższy fragment jest pomocny tym, którzy chcą użyć zmiennej w środku.

const myVar = 'not';
<MyComponent text={["This is ", <strong>{`${myVar}`}</strong>,  "working."]} />
Jaison
źródło
1

W moim projekcie musiałem przekazać dynamiczny fragment kodu HTML ze zmiennej i wyrenderować go wewnątrz komponentu. Więc zrobiłem co następuje.

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

Obiekt defaultSelection jest przekazywany do komponentu z .jspliku

<HtmlSnippet innerHtml={defaultSelection.innerHtml} />

Komponent HtmlSnippet

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

Przykład Plunkr

zareaguj doc na niebezpiecznieSetInnerHTML

Rajkishor Sahu
źródło
1

Możesz również użyć funkcji na komponencie, aby przekazać plik jsx do właściwości. lubić:

 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
źródło
1

Tak, możesz to zrobić, używając tablicy mix z ciągami znaków i elementami JSX. odniesienie

<MyComponent text={["This is ", <strong>not</strong>,  "working."]} />
Osama Bari
źródło
1

Parser z html -active-parser to dobre rozwiązanie. Ty po prostu musisz

  • zainstaluj go za pomocą npm lub przędzy
  • import Parser z 'html -active-parser';
  • zadzwoń z:

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

    i działa dobrze.

Franck212
źródło
1

Dodając do odpowiedzi: Jeśli zamierzasz parsować i jesteś już w JSX, ale masz obiekt z zagnieżdżonymi właściwościami, bardzo eleganckim sposobem jest użycie nawiasów w celu wymuszenia parsowania JSX:

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

To pytanie ma już wiele odpowiedzi, ale zrobiłem coś złego w związku z tym i myślę, że warto się nim podzielić:

Miałem coś takiego:

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

ale masaż był dłuższy, więc spróbowałem użyć czegoś takiego:

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

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

Zajęło mi trochę czasu, zanim zdałem sobie sprawę, że brakuje mi () w wywołaniu funkcji.

Nie działa

<Section message={message} />

Pracujący

<Section message={message()} />

może to ci pomoże, tak jak mnie!

Abraham Hernandez
źródło
1

Możesz z powodzeniem wykorzystać fragmenty Reacta do tego zadania. W zależności od wersji używanego React, można użyć składni: krótkie <>lub pełną tag: <React.Fragment>. Działa szczególnie dobrze, jeśli nie chcesz zawijać całego ciągu w znaczniki HTML.

<MyComponent text={<>Hello World. <u>Don't be so ruthless</u>.</>} />
Cyklon
źródło
0

W ten sposób możemy zrobić to samo.

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

teraz chcesz wysłać ten kod HTML do innego komponentu, którego nazwa to komponent nadrzędny.

Dzwonię: -

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

Korzystanie z dziecka: -

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

ta praca jest dla mnie idealna.

pushparmar
źródło
-9

Dołączyły kod HTML w module componentDidMount przy użyciu jQuery append. To powinno rozwiązać problem.

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

        return (
           <div>

           </div>
        );
    },
    componentDidMount() {
        $(ReactDOM.findDOMNode(this)).append(this.props.text);
    }
});
Kaushik
źródło
5
To jest głosowanie negatywne, ponieważ nie powinieneś używać bezpośredniej manipulacji DOM w jquery w połączeniu z pośrednią manipulacją DOMEM, ponieważ może to prowadzić do zepsucia przeglądarki.
Allison