Reactコンポーネントが吐き出す HTML をいい感じに整形して表示する
Reactコンポーネントが吐き出す HTML を React でいい感じに表示するという、とてもピンポイントな記事です。
表示したい元となるコンポーネントを Hoge
とします。
const Hoge: React.FC = () => {
return <div><div>hoge</div><div>fuga</div><p>piyo</p></div>
}
この Hoge がレンダリングするものをインデントなどを整形してシンタックスハイライトまで行って、いい感じに表示します。
ちょっと特殊なツールを作りたい人にしか需要がない記事だとは思います。
インストール
npm派のひとは、yarn add
を npm i
に読み替えてください。
$ yarn add react-highlight.js prettier
$ yarn add @types/prettier @types/react-highlight.js -D
HTMLソースを整形してするために prettier
と、シンタックスハイライトするために react-highlight.js
をインストールします。
ちなみに、ReactなりNextなりは動いているものとします。
整形する
Reactコンポーネントの吐き出すHTMLを整形します。
import { renderToStaticMarkup } from 'react-dom/server'
import { format } from 'prettier/standalone'
import parserHTML from 'prettier/parser-html'
const formatToHTML = (element: JSX.Element) =>
format(renderToStaticMarkup(element), {
parser: 'html',
plugins: [parserHTML],
})
renderToStaticMarkup
で JSX.Element
たとえば <Hoge />
の中の HTML をレンダリングして取り出します。
このとき返ってくる文字列は <div><div>hoge</div><div>fuga</div><p>piyo</p></div>
です。元々のコンポーネントのソースコードがどういうインデントスタイルであったとしても、余分なインデントや改行を入れることはありません。
そこで、これを人間が読みやすいように、prettier/standalone
の format
と、HTML処理用のプラグインとして parserHTML
を使います。
その結果、得られるのが、
<div>
<div>hoge</div>
<div>fuga</div>
<p>piyo</p>
</div>
という文字列になります。
さて、Hoge
コンポーネントの吐き出すHTMLを、インデント済みのHTMLとして文字列で取得するところまでできました。
次は、シンタックスハイライトです。
シンタックスハイライトする
シンタックスハイライトは簡単です。
import Highlight from 'react-highlight.js'
で Highlight
コンポーネントを読み込んで、<Highlight language="html">{source}</Highlight>
のように実行するだけです。
プロパティで JSX.Element
を受け取って HTML としてレンダリングする RenderReactHTML
というコンポーネントを作ってみましょう。
import Highlight from 'react-highlight.js'
import 'highlight.js/styles/github.css'
type Props = {
element: JSX.Element
}
const RenderReactHTML: React.FC<Props> = ({ element }) => {
const source = React.useMemo(() => {
return formatToHTML(element)
}, [element])
return (
<div>
<Highlight language="html">{source}</Highlight>
</div>
)
}
このコンポーネントは、<RenderReactHTML element={<Hoge />} />
のように使います。
これで、冒頭のスクショのような表示結果が得られます。
Discussion
この記事のおかげで困っていたことが解決できました!
ありがとうございます😄