Welcome :っ)

Devlog/Front-End

[NextJS] SSR 이슈 (Warning: Prop dangerouslySetInnerHTML did not match.)

lazy.won 2022. 10. 19. 16:08
728x90
반응형

 

 

Next.js를 이용하여 정적 블로그 개발 중 포스팅한 블로그 글 페이지 콘솔에 다음과 같은 warning이 발생하였다. 
 
 
 
 
 
 

💡 dangerouslySetInnerHTML란?

현재 블로그 포스팅을 위해 포스팅할 마크다운 파일을 가져와서 `remark-html`로 파싱하여 HTML string 형태로 변환해주고 있다. 
 
dangerouslySetInnerHTML은 브라우저 DOM에서 innerHTML을 사용하기 위한 React의 대체 방법이다. 
 
일반적으로 코드에서 HTML을 설정하는 것은 XSS 공격에 쉽게 노출될 수 있어 위험(html 내부 script로 인해 유저의 쿠키 등 개인 정보를 탈취할 수 있기 때문)하다.
따라서 React에서 직접 HTML을 설정할 수는 있지만, 위험하다는 것을 상기시키기 위해 dangerouslySetInnerHTML을 작성하고 __html키로 파싱한 HTML 컨텐츠 객체를 전달함으로써 화면에 출력한다. 
 
<div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />

 

 

 

해결방법 🍏

Next.js와 같은 SSR의 경우, dangerouslySetInnerHTML을 통해 콘텐츠를 보여주기 전에, component가 먼저 마운트 되었는지 확인해야 한다. 

 

React useEffect는 마운트가 되었을 때 실행된다. 다시말해, useEffect를 사용하여 SSR로 받은 HTML을 받은 후에 dangerouslySetInnerHTML이 동작하도록 해야 한다. 

 

따라서 아래와 같이 dangerouslySetInnerHTML가 서버에서 렌더링되지 않도록, React의 useState와 useEffect hooks을 사용하여 마운트 된 경우에 dangerouslySetInnerHTML에 content 객체를 전달하도록 하였다. 

 

import { useState, useEffect } from 'react';

export default function ParentComponent({ content }) {
    const [mounted, setMounted] = useState<boolean>(false);
    
    useEffect(() => {
    	setMounted(true);
    }, []);
    
    return <div dangerouslySetInnerHTML={{ __html: mounted && postData.contentHtml }} />
}

 

 

그 결과, 아래와 같이 warning을 없앨 수 있었다 ! 

까알꼼한 결과

 

 

 

 

 

 

 

참고

https://stackoverflow.com/questions/64079321/react-tooltip-and-next-js-ssr-issue

320x100
반응형