์ด ์ ์ ํฌ์คํธ์์ react-quill์ ์ด์ฉํด์ ๊ฒ์๊ธ์ ์์ฑํ๋๋ฐ, ํด๋น ๊ฒ์๊ธ์ ๋ด์ฉ์ ๋ฐฑ์๋์ ์ ๋ฌํด์ฃผ๊ณ , ๊ทธ ๊ฐ์ ๋ฐ์์ค๋ ๊ณผ์ ์์ error๊ฐ ๋ฐ์ํด์ ๋ฌธ์ ์ ์ ์ฐพ๊ณ ํด๊ฒฐํ๊ณ ์ ํ๋ค.
react-quill์์ ๋ฐฑ์๋๋ก ๋๊ฒจ์ค ๋ </> ํ๊ทธ ํํ๋ก ๋๊ฒจ์ฃผ๋๋ฐ, ๋ฐ์ ๋๋ ํ๊ทธ์ ๋ด๊ฒจ์ ธ์ ๋ค์ด์๋ค. ์ฌ์ค ์ด error๋ฅผ ํด๊ฒฐํ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ๋ฐฑ์๋ ๋ก์ง์ ๋ฐ๊ฟ์ ํ๊ทธ๊ฐ ์๋ ์ํ๋ก api๋ฅผ ๋ณด๋ด์ฃผ๋ ๊ฒ์ด ์๋๋ผ ํ๊ทธ๋ฅผ ๋ฒ๊ธด ์ํ๋ก ๊ฐ์ ์ ๋ฌํด ์ฃผ๋๊ฒ ๊ฐ์ฅ ์ข๋ค๊ณ ํ๋ค. ๊ทธ๋ฐ ์ํฉ์ด ์๋์จ๋ค๋ฉด ๋์ฒ๋ผ...
<div dangerouslySetInnerHTML={{ __html: isData.body }} />
์ฒ์์๋ ์ด๋ ๊ฒ divํ๊ทธ๋ก ์ด๋ฃจ์ด์ง ๊ฐ์ isData.body์ฆ, ๋ณธ๋ฌธ ๋ด์ฉ๊ฐ์ ๋ฐ์๋ค. ์ด๋ ๊ฒ ํ๊ณ ๋ ๋๋ง์ ํด๋ณด๋ ๋์ฉ ์๋ฌ๊ฐ ๋ง๊ตฌ๋ง๊ตฌ ๋จ๋๊ฒ์ด๋ค.
ํด๋น ์๋ฌ์์ Hydration์ด๋ผ๊ณ ๋ฌ๋๋ฐ Hydration์ ์์ธํ๊ณ ์ ํํ ๋ด์ฉ์ ์ง์ ์ฐพ์๋ณด๊ณ , ์ฝ๊ฒ ์ด์ผ๊ธฐ ํ์๋ฉด,
ssr์์ ๊ฐ์dom์์ ๋ ๋๋ง๋ ํ์ด์ง์ javascript์ฝ๋๊ฐ ๋ด๊ฒจ์ ธ์ ์ค์ dom์์์ ๋ค์ ๋ ๋๋ง๊ณผ์ ์ ๊ฑฐ์น๋ฉด์ ๊ฐ์ ํ์ธํ๋๋ฐ,
window์ ๊ด๋ จ๋ ๊ฐ์ด ๋ค์ด๊ฐ๋ฉด, ๊ฐ์dom์์ ๋ ๋๋ง๋ ๋ด์ฉ๊ณผ, ์ค์ dom์์ ๋ ๋๋ง๋ ๋ด์ฉ์ด ๋ฌ๋ผ์ ๋๋ ์ค๋ฅ๋ผ๊ณ ํ๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ์ useEffect๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, next/dynamic์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ธ๋ฐ,
next/dynamic์ ์ด๋ฏธ react-quill์ ์์ฑํ๋ฉด์ ์ ์ด๋์๋ค.
const QuillWrapper = dynamic(() => import('react-quill'), {
ssr: false,
loading: () => <p>Loading ...</p>,
});
๊ทผ๋ฐ ๋๋ ์ด๋ ๊ฒ ํ๋๋ฐ ์๋๊ธธ๋ ์๋ผ ๋ชจ๋ฅด๊ฒ ๋ค ํ๊ณ , useEffect๋ฅผ ์ฌ์ฉํด ๋ณด์๋ค.
์ฒ์์ useEffect์ ํ๊ทธ๋ฅผ ์ด๋ป๊ฒ ํ๋ฉด ๋ด์ ์ ์์๊น ์๊ฐํ๋ค๊ฐ ๊ทธ๋ฅ ๋จ์ํ๊ฒ boolean๊ฐ์ state๋ก ์ ์ธํ๊ณ ์ฌ์ฉํ๋ค.
const [getState, setState] = useState<boolean>(false);
useEffect(() => { //๋ง์ดํธ์ ๋์์ true๊ฐ์ผ๋ก ๋ฐ๊ฟ์ ssr๋ฌธ์ ํด๊ฒฐ!
setState(true);
}, []);
...
return ({getState && <div dangerouslySetInnerHTML={{ __html: isData.body }} />});
์ด๋ฐ์์ผ๋ก ์ฌ์ฉํ๋๊น ์๋ฌ๊ฐ ์ฌ๋ผ์ก๋ค!
HTML๊ณผ ํจ๊ป ๋ณด๋ด๋ ๊ฒ์ด๊ธฐ์ ํธ๋ฆด ์ํ์ด ์๋ค.
๊ทธ๋์ dompurify
๋ฅผ ์ฌ์ฉํด์ ํธ๋ฆฌ๋๊ฒ์ ๋ฐฉ์งํ๋ค