ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React를 사용할 때, HTML을 직접 삽입하기 - dangerouslySetInnerHTML 사용 예제
    React 2025. 4. 20. 20:02

    React를 쓰다 보면, HTML 문자열을 그대로 DOM에 삽입해야 하는 상황이 종종 있다.

     

    예를 들어 CMS에서 내려오는 콘텐츠, 외부 라이브러리에서 생성된 HTML, 혹은 서버에서 렌더링된 일부 HTML 조각 등을 사용할 때 그렇다.

     

    그런데 React에서는 일반적으로 HTML 문자열을 직접 넣을 수 없다.

    그래도 넣어야 하는 경우가 있다면 사용할 수 있는 게 바로 dangerouslySetInnerHTML인데, 이름부터 위험하듯, 조심스럽게 사용해야 한다.

     

    🤔 왜 dangerouslySetInnerHTML일까?

    React는 XSS(Cross-Site Scripting) 공격을 방지하기 위해 JSX 내부에서 HTML 문자열을 직접 렌더링하지 못하게 막는다.

    그래서 HTML 문자열을 렌더링하려면 특별한 방법이 필요하다.

    <div dangerouslySetInnerHTML={{ __html: '<strong>Hello World</strong>' }} />
     

    __html과 같은 이상한 이름이 사용된 것은, React 팀이 일부러 이렇게 만들었기 때문이다.

     

    이걸 쓰는 건 위험하니까, 정말 위험하다는 걸 사용자가 인지하고 쓰라는 의미로 일부러 "dangerously"라는 네이밍을 넣은 것이라고 한다.

     

    ✅ 사용 예제

    CMS에서 HTML 콘텐츠가 내려오는 상황을 예로 들어보자

     
    type ArticleProps = {
      content: string; // 서버에서 받은 HTML 문자열
    };
    
    function Article({ content }: ArticleProps) {
      return (
        <div className="article-content" dangerouslySetInnerHTML={{ __html: content }} />
      );
    }
     

    이런 식으로 서버에서 받은 HTML을 그대로 삽입할 수 있다 (content는 HTML 문자열)

     

    ⚠️ 주의할 점 (중요!)

    1. XSS 공격에 취약

    가장 큰 위험 요소는 XSS 공격이다.

    만약 content에 <script>alert("XSS")</script> 같은 게 들어온다면 그대로 실행이 되어 버린다.

    사용자가 입력한 값이 서버에서 필터링되지 않고 넘어온다면… 보안에 아주 위험하다.

    항상 신뢰할 수 있는 콘텐츠만 삽입하거나, 반드시 서버단에서 sanitize(정화)된 데이터를 사용하도록 하자!

     

    2. React의 Virtual DOM과의 궁합이 나쁠 수 있음

    React는 DOM을 Virtual DOM으로 관리하는데, dangerouslySetInnerHTML로 삽입된 내용은 React가 직접 관리하지 않는다.

    그래서 이 안에 있는 DOM 요소를 React 방식으로 업데이트하거나 이벤트를 걸 수 없는 문제가 있다.

     

    3. CSS-in-JS, Tailwind 같은 스타일링 시스템과 충돌 가능성

    내용이 외부 HTML로 들어오다 보니, 우리가 기존에 쓰던 스타일링 방식이 적용되지 않거나, 충돌이 날 가능성이 있다.

     

    ✅ 장점

     

    ✅ 외부 HTML 콘텐츠 렌더링 가능 CMS, Markdown 파서, WYSIWYG 에디터 같은 데서 생성된 HTML을 그대로 사용할 수 있음
    ✅ 간단한 마크업 처리 <strong>, <em>, <ul> 같은 간단한 마크업을 빠르게 렌더링할 수 있음

     

     

    ❌ 단점


     

    ❌ XSS 취약성 보안 문제를 반드시 고려해야 함
    ❌ Virtual DOM 미사용 React가 내용을 추적하거나 관리하지 않음
    ❌ 유지보수 어려움 렌더링된 내용의 구조를 알기 어려워 테스트/디버깅이 까다로움

     

    ✅ 안전하게 쓰려면?

    1. 서버에서 HTML Sanitizer를 반드시 거치자!
      • DOMPurify, sanitize-html, 서버단 필터링
    2. 완전한 신뢰가 가능한 콘텐츠만 사용하자
      • 본인이 작성한 고정 콘텐츠, 내부 전용 CMS
    3. 가능하다면 HTML 문자열 대신 React 컴포넌트로 구조화하자
      • Markdown → React로 파싱 (remark, rehype, etc.)

     

    ✍️ 요약하자면....

    dangerouslySetInnerHTML는 이름부터 경고를 날리는 기능이지만, 정말 필요한 상황에선 유용하게 쓰일 수 있다.

    단, 무조건 보안을 고려해야 한다. (위험한 기능은 쓰지 않는 게 가장 안전하지만, 써야 한다면 제대로 알고 써야 한다.)

Designed by Tistory.