React

dangerouslySetInnerHTML

hyeone22 2024. 12. 26. 15:39

0. 해당 글을 작성하게 된 계기

해당 글을 작성하게 된 계기는 에디터 편집 과정에 있습니다.

에디터는 사용자가 작성한 HTML 콘텐츠를 저장하고 이를 다시 렌더링 하는 기능이 필수적입니다.

이 과정에서 dangerouslySetInnerHTML를 사용하는 코드가 발견되었고, 이에 대한 이해가 필요했습니다.

1.0. dangerouslySetInnerHTML란 무엇인가?

1. dangerouslySetInnerHTML 은 React에서 원시 HTML을 컴포넌트에 삽입할 수 있도록 해주는 특수한 속성이다.

2. 일반적으로 React는 JSX를 통해 DOM을 관리하지만, 이 속성은 React의 가상 DOM을 우회하여 HTML 문자열을 DOM에 직접 삽입한다.

3. 이 기능은 잠재적인 보안 취약점, 특히 XSS(교차 사이트 스크립팅) 공격의 위험성을 강조하기 위해 “dangerously”라는 이름이 붙었다.

 

1.1. 사용 이유

1. 타사 콘텐츠 통합 - 광고나 위젯 같은 외부 소스에서 제공하는 사전 포맷된 HTML을 통합할 때

2. 콘텐츠 관리 시스템(CMS) - 많은 CMS 플랫폼은 동적 콘텐츠를 위해 HTML 문자열을 저장하고 제공하며, 이를 애플리케이션에서 렌더링해야 할 때

3. 레거시 HTML - 이전 시스템과 호환성을 유지하기 위해 원시 HTML 삽입이 필요한 경우

4. 성능 최적화 - 드물지만, JSX를 통해 동적으로 생성하는 것보다 정적 마크업을 직접 삽입하는 것이 더 빠를 때가 있다.

1.1.1. 성능최적화 - 특정 사례

드물게, 정적 마크업을 dangerouslySetInnerHTML로 삽입하는 것이 JSX를 통해 동적으로 생성하는 것보다 더 빠른 경우가 있다.

정적 마크업의 직접 삽입

1. 사전에 생성된 HTML이 크고 복잡하며, 이 HTML이 동적으로 업데이트될 필요가 없을 때

2. 예를 들어, 서버에서 미리 생성된 HTML 콘텐츠를 클라이언트에 렌더링 할 경우, JSX 변환 없이 직접 DOM에 삽입하면 성능이 개선될 수 있다.

const staticHtml = '<div><h1>Welcome!</h1><p>이 콘텐츠는 정적으로 생성되었습니다.</p></div>';

function StaticContent() {
  return <div dangerouslySetInnerHTML={{ __html: staticHtml }} />;
}

 

JSX 변환의 비용 회피

JSX는 가상 DOM 요소를 생성하는 추가 작업이 필요합니다. 대규모 정적 콘텐츠를 JSX로 변환하면 성능에 부정적인 영향을 미칠 수 있지만, dangerouslySetInnerHTML를 사용하면 이를 방지할 수 있다.

레거시 콘텐츠와의 호환성

이전 시스템이 HTML 문자열을 반환할 때, 이를 JSX로 변환하는 대신 직접 DOM에 삽입하면 더 간단하고 빠르다.

결론

dangerouslySetInnerHTML는 React에서 강력한 도구이지만, 신중하게 사용해야 한다.
DOMPurify와 같은 라이브러리를 사용해 입력을 정제하여 XSS 위험을 완화하고,
JSX 또는 다른 안전한 대안이 실현 불가능할 때만 이 기능에 의존하는 것이 좋다.

1.2. 사용 방법

dangerouslySetInnerHTML를 사용하려면, __html 키와 함께 HTML 문자열이 포함된 객체를 제공해야 한다.

 

사용 예제

function Example() {
  const HtmlContent = '<p>이것은 <strong>굵게</strong> 표시된 텍스트가 포함된 단락입니다.</p>';

  return (
    <div dangerouslySetInnerHTML={{ __html: rawHtmlContent }} />
  );
}

1.3. 유의 사항

1. __html 속성은 원시 HTML을 사용할 의도가 있음을 명시적으로 나타내기 위해 필요하다.

2. 신뢰할 수 없거나 정제되지 않은 콘텐츠와 함께 dangerouslySetInnerHTML를 사용하지 않는 것이 좋다.

1.4. 장점과 단점

장점

1. 유연성 - 외부 또는 레거시 시스템에서 제공되는 원시 HTML 콘텐츠를 JSX로 변환하지 않고도 렌더링 할 수 있습니다.

2. 통합 용이성 - 광고 또는 임베디드 위젯과 같은 타사 서비스를 간단하게 포함할 수 있습니다.

3. 동적 콘텐츠 렌더링 - 데이터베이스에 저장되거나 API에서 가져온 HTML 콘텐츠를 렌더링하기에 적합합니다.

 

단점

1. 보안 위험 - 삽입된 HTML이 정제되지 않은 경우, XSS 공격에 노출될 수 있습니다.

2. React 제어 손실 - React의 선언적 특성과 가상 DOM의 이점을 우회하기 때문에 성능 문제나 디버깅 어려움이 발생할 수 있습니다.

3. 가독성 저하 - dangerouslySetInnerHTML를 사용하는 코드는 JSX보다 읽기 어렵고 유지 관리가 어렵습니다.