はじめに
ReactのdangerouslySetInnerHTML
とは、生のHTMLをReactコンポーネントに直接注入するためのプロパティです。
例)
index.tsx
const content = '<a href="https://www.google.com" target="_blank">クリック</a>'
return (
<div dangerouslySetInnerHTML={{ __html: content }}></div>
)
このプロパティを使ってしばしば外部コンテンツを表示したり、
ユーザーの入力をプレビューしたりすることがあります。
そう、丁度こんな風に
![]()
そんなdangerouslySetInnerHTML
を初回描画時に読み込むとHydration failed
のエラーになりましたので、その解決方法です。
原因
Hydration failed
とは、
サーバーサイドでレンダリングされたHTMLと、
クライアントサイドでレンダリングされたHTMLとの間で
不一致があるときに発生します。
つまり最初の例の場合、
サーバーサイド
<div></div>
クライアントサイド
<div>
<a href="https://www.google.com" target="_blank">クリック</a>
</div>
のように差が発生しているためエラーになっていました。
対処法
useEffect
を使う
useEffectを使い、最初のレンダリング後に表示したいものを表示する
index.tsx
const [content, setContent] = useState()
useEffect(() => {
setContent('<a href="https://www.google.com" target="_blank">クリック</a>')
}, [])
return (
<div dangerouslySetInnerHTML={{ __html: content }}></div>
)
こうすることで、サーバーサイドとクライアントサイドのレンダリングの差異を無くすことができました