React: Jak wyrenderować HTML, który jest przechowany w zmiennej?

Aby wyrenderować HTML przechowywany w zmiennej w React, należy zrozumieć różnicę między renderowaniem JSX a dynamicznym wstrzykiwaniem „czystego” HTML. React domyślnie nie pozwala na bezpośrednie inserowanie nieprzetworzonego HTML do komponentów, co związane jest z bezpieczeństwem (ochrona przed XSS). Jednak są sytuacje, w których taka funkcjonalność jest oczekiwana – na przykład przy renderowaniu treści pochodzących z CMS lub API. Najważniejsze metody i najlepsze praktyki opisano poniżej wraz z przykładami.

Standardowe renderowanie – JSX w zmiennej

Jeśli do zmiennej przypiszemy element lub fragment JSX, wstawienie jej do komponentu jest bezpieczne i proste:

const htmlFragment = <strong>To jest pogrubiony tekst</strong>;
function Example() {
  return (
    <div>
      {htmlFragment}
    </div>
  );
}

Takie podejście zalecane jest wtedy, gdy kontrolujemy źródło danych i wiemy, że fragment jest tworzony w kodzie React.

Renderowanie HTML jako tekstu (niebezpieczne)

Jeśli w zmiennej znajduje się string z kodem HTML i chcemy, aby React wyrenderował go jako realny HTML, korzysta się ze specjalnego mechanizmu:

Wbudowana właściwość dangerouslySetInnerHTML

React pozwala na ustawienie zawartości elementu DOM przez dangerouslySetInnerHTML, np.:

const htmlString = '<span style="color: red;">Niebezpieczny HTML</span>';
function Example() {
  return (
    <div dangerouslySetInnerHTML={{ __html: htmlString }} />
  );
}

Uwaga – to rozwiązanie należy stosować tylko wtedy, gdy kod HTML jest w pełni zaufany. W przeciwnym razie narażamy aplikację na ataki typu Cross Site Scripting (XSS). Najlepiej oczyszczać takie dane przed wyświetleniem.

Zastosowania praktyczne

  • Wyświetlanie artykułów z CMS – kiedy treść wpisu pobierana jest z WordPressa lub podobnego systemu, zachodzi konieczność renderowania HTML dostarczonego z zewnątrz;
  • Podgląd wygenerowanego kodu – np. w edytorach „WYSIWYG”;
  • Elementy reklamowe lub widgety – często dostarczane jako fragmenty HTML.

Przykład – komponent do renderowania zewnętrznego HTML

function HtmlContent({ html }) {
  return (
    <div dangerouslySetInnerHTML={{ __html: html }} />
  );
}

// Przykładowe użycie
const externalHtml = "<h2>Aktualności</h2><p>To jest <em>dynamiczna</em> treść!</p>";

function App() {
  return <HtmlContent html={externalHtml} />;
}

Renderowanie warunkowe fragmentu HTML

Możesz decydować o tym, czy HTML zostanie wyrenderowany w zależności od warunku logicznego:

function ConditionalHtml({ isVisible, html }) {
  if (!isVisible) return null;
  return <div dangerouslySetInnerHTML={{ __html: html }} />;
}

// Użycie:
<ConditionalHtml isVisible={true} html="<p>Pojawię się tylko, jeśli isVisible=true!</p>" />

Można używać instrukcji if, operatora && lub warunkowego ? :, by sterować widocznością.

Najlepsze praktyki i podsumowanie

  • Jeśli tylko możliwe korzystaj z JSX — jest bezpieczny, czytelny i wydajny,
  • korzystaj z dangerouslySetInnerHTML tylko gdy musisz i masz pewność co do źródła HTML,
  • Sanityzuj HTML pochodzący z niezaufanego źródła – użyj bibliotek do oczyszczania HTML,
  • przechowuj gotowy JSX jako zmienne, jeśli cały kod generowany jest po stronie Reacta.

Dobrym zwyczajem jest dokumentowanie miejsc, w których korzystasz z „niebezpiecznego” renderowania HTML i regularna kontrola źródeł danych przekazywanych do takich komponentów. Szczegółowe omówienie renderowania JSX oraz warunkowego znajdziesz w dokumentacji oraz licznych poradnikach dla React.

Programista i twórca serwisu Creative Coding, absolwent Politechniki Warszawskiej (WEiTI). Od 10+ lat łączy front‑end, grafikę generatywną i narzędzia dla twórców; opublikował 120+ projektów i artykułów, prowadził warsztaty dla 2 000+ uczestników. Pracuje z JavaScriptem, Three.js, P5.js i GLSL, bada wydajność i dokumentuje procesy, tworząc praktyczne przewodniki dla osób łączących kod z obrazem, dźwiękiem i interakcją.
Zostaw komentarz

Komentarze

Brak komentarzy. Dlaczego nie rozpoczniesz dyskusji?

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *