LoginSignup
0
0

More than 1 year has passed since last update.

gatsby-remark-componentで外部から値を注入する方法

Posted at

はじめに

こんにちは。最近は本業でRailsを触ってばかりの日々が続いております。

さて、今回はGatsbyでカスタムコンポーネントを使用しているのですが、コンポーネント外部から値を注入する方法について記載します。

参考になれば幸いです:pray:

(ぜひLGTMいただけましたら:smile:

Gatsbyでコンポーネントの作り方はこちら

結論

コンテンツ

記事のマークダウン内に以下のようにコンポーネントを呼び出す場合。

post.md
<custom-component name="こんにちは"></custom-component>

コンポーネントの実態

src/components/CustomComponent.js
import React from 'react'

const CustomComponent = props => (
  <div>
      <p>{props.name}</p>
      <p>{props.keywords}</p>
  </div>
)

export default CustomComponent

コンポーネント突合

src/components/PageBody.js
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

解説

普通にコンポーネントから値を渡すパターン

記事のマークダウン内に以下のようにコンポーネントを呼び出す

post.md
<custom-component name="こんにちは"></custom-component>

コンポーネント内では以下のように、propsに渡ってくるのでそれをレンダリングするだけ。

src/components/CustomComponent.js
import React from 'react'

const CustomComponent = props => (
  <div>
      <p>{props.name}</p>
  </div>
)

export default CustomComponent

今回は外部から注入するパターンを追加

以下例では、ページ別で管理しているkeywordsの値をマークダウンからねじ込むコンポーネントに注入します。

keywordsはPageBodyを呼び出した際にpropsで渡ってきます。

それをcustom-componentCustomComponentに置き換える際に、コンポーネントが持っている値にkeywordsをマージして呼び出しています。

src/components/PageBody.js
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作成前にいじるなども考えましたが、この方法が一番スマートに思います。

参考になれば幸いです:pray:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0