はじめに
こんにちは。最近は本業でRailsを触ってばかりの日々が続いております。
さて、今回はGatsbyでカスタムコンポーネントを使用しているのですが、コンポーネント外部から値を注入する方法について記載します。
参考になれば幸いです
(ぜひLGTMいただけましたら)
Gatsbyでコンポーネントの作り方はこちら
結論
コンテンツ
記事のマークダウン内に以下のようにコンポーネントを呼び出す場合。
<custom-component name="こんにちは"></custom-component>
コンポーネントの実態
import React from 'react'
const CustomComponent = props => (
<div>
<p>{props.name}</p>
<p>{props.keywords}</p>
</div>
)
export default CustomComponent
コンポーネント突合
import React from 'react'
import CustomComponent from "../components/CustomComponent"
import RehypeReact from "rehype-react"
const PageBody = props => {
const renderAst = new RehypeReact({
createElement: React.createElement,
components: {
"custom-component": p => CustomComponent({...p, {keywords: props.keywords}})
}
}).Compiler
return (
<Body>
{renderAst(props.body.childMarkdownRemark.htmlAst)}
</Body>
)
}
export default PageBody
解説
普通にコンポーネントから値を渡すパターン
記事のマークダウン内に以下のようにコンポーネントを呼び出す
<custom-component name="こんにちは"></custom-component>
コンポーネント内では以下のように、propsに渡ってくるのでそれをレンダリングするだけ。
import React from 'react'
const CustomComponent = props => (
<div>
<p>{props.name}</p>
</div>
)
export default CustomComponent
今回は外部から注入するパターンを追加
以下例では、ページ別で管理しているkeywordsの値をマークダウンからねじ込むコンポーネントに注入します。
keywordsはPageBodyを呼び出した際にpropsで渡ってきます。
それをcustom-component
をCustomComponent
に置き換える際に、コンポーネントが持っている値にkeywordsをマージして呼び出しています。
import React from 'react'
import CustomComponent from "../components/CustomComponent"
import RehypeReact from "rehype-react"
const PageBody = props => {
const renderAst = new RehypeReact({
createElement: React.createElement,
components: {
"custom-component": p => CustomComponent({...p, {keywords: props.keywords}}) // ここでコンポーネントにpropsにkeywordsをマージする。
}
}).Compiler
return (
<Body>
{renderAst(props.body.childMarkdownRemark.htmlAst)}
</Body>
)
}
export default PageBody
おわりに
Contentfulでコンテンツを管理しているのですが、そのコンテンツ内にカスタムコンポーネントを記載しています。
そのコンポーネントでコンテンツ固有の値を使用する場合に、このような記述が必要になりました。
当初は、マークダウンのコンテンツをContentfulからfetchした際に、node作成前にいじるなども考えましたが、この方法が一番スマートに思います。
参考になれば幸いです