Frameworks, Platforms and Libraries/React

String to HTML, dangerouslySetInnerHTML

iam102 2024. 6. 9. 14:22

데이터로 String화된 HTML을 React에서 적용 시 dangerouslySetInnerHTML를 사용합니다. 네이밍부터 dangerously가 들어가지만 무심코 사용하는 dangerouslySetInnerHTML에 대해 알아보겠습니다.

 

dangerouslySetInnerHTML?

dangerouslySetInnerHTML은 React에서 innerHTML을 사용하기 위한 방법으로 String으로 된 HTML을 그대로 사용하는 것을 막고 __html 키로 객체를 전달해 사용합니다.

function Component() {
  const markup = '<p>some raw html</p>';
  
  return <div dangerouslySetInnerHTML={{ __html: markup }} />;
}

export default Component;

 

예시에서 확인할 수 있듯이 dangerouslySetInnerHTML을 사용하면 해당 element는 child element를 가질 수 없고 self-closing tag로 사용해야 합니다.

 

dangerouslySetInnerHTML는 네이밍에서도 알 수 있듯이 사용에 있어 주의해야 합니다. DOM에서 innerHTML을 사용하는 것과 마찬가지로 스크립트 코드를 심어 공격하는 사이트 간 스크립팅(XSS, Cross-Site Scripting) 공격에 취약점을 가지기 때문에 사용에 유의해야 합니다.

 

dangerouslySetInnerHTML vs innerHTML

React에서 innerHTML이 아닌 왜 dangerouslySetInnerHTML을 사용할까?라는 의문이 생깁니다. Virtual DOM을 사용하는 React에서 innerHTML 사용 시 DOM 노드가 수정되었는지 알 수 있는 방법이 없는 이슈가 있습니다. 또한 dangerouslySetInnerHTML을 사용하면 HTML이 다른 소스에서 온다는 것을 미리 알기 때문에 해당 노드의 하위 항목을 확인하는 것을 우회하여 성능 향상을 얻을 수 있습니다.따라서 성능 향상과 DOM 변경 체크를 위해 React에선 dangerouslySetInnerHTML을 사용합니다.

 

마무리

dangerouslySetInnerHTML을 사용하면서 XSS 공격을 방지하기 위해 XSS sanitizer인 DOMPurify를 활용하는 방법이 있습니다. 참고하면 좋겠습니다. dangerouslySetInnerHTML의 무분별한 사용을 지양하고 사용하더라도 안전하게 사용할 수 있도록 고민해야겠습니다.


참고 자료

https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html

https://blog.logrocket.com/using-dangerouslysetinnerhtml-react-application/

https://stackoverflow.com/questions/37337289/react-js-set-innerhtml-vs-dangerouslysetinnerhtml