2017-10-02 21 views
3

Gatsbyでは、独自のgraphqlクエリを持つ再利用可能なコンポーネントを構築することは現在可能ですか?そうでない場合、現在のところ、再利用可能なコンポーネントにデータを渡すための最小限の "結合された"方法はありますか?私はこれを行う例を見つけることができないと私はドキュメントで何も見つけることができません。Gatsby独自のクエリで再利用可能なコンポーネント

例えば、すべての「投稿」ページのサイドバーや単一の「/タグクラウド」ページに表示されるブログのタグクラウドコンポーネントを作成したいとします。 <TagCloud limit={20} />または<TagCloud tags={uniqueTags} />のように使用できます。このためには、すべてのエッジを照会する必要があります。各tagsの配列を一意の順序付けされた一意のタグ文字列にmap-reduce/extractします。

または、現在の製品を除いたカタログページの「他の製品」コンポーネントが必要だったとします。ここには<ProductsList exclude={currentProduct} />があるかもしれません。これは、構築時に直接フィルタリングされたクエリになります。

私が見ることができる唯一の方法は、createPages()のクエリ結果をモンキーパッチするか、またはcreatePage({path, component, context})contextでデータを渡すことです。これはgatsby-node.jsで行われるべきですか?他の方法はありますか?

+2

クイック答えはhttps://github.com/gatsbyjs/gatsby/search?utf8=%E2%9C%93&q=fragment&type=うまくいけば、I'LLヘクタールの断片であります間もなくこれについて書類を書く時間を割いてください。 –

+0

ありがとう@KyleMathews(そしてギャツビーのために多くの感謝)。私が終わったら、私は調査し、更新します。 – Andrew

+0

@KyleMathews - まだ見ていない。フラグメント(クエリ内)は、それらが展開する単一のグラフエッジのみを受け取るようです。 'allMarkdownRemark'のようにアクセスできる例はありません。アバターの例では、1つの投稿ページにすべてのサイト作成者のすべてのアバターのリストをどのように表示しますか?あるいは、 'gatsby-node.js'でリストを作成できたら、それをどのページに渡すべきですか? – Andrew

答えて

1

私は自分自身の質問に答えています。誰かがより良い解決策を持っているなら、それを提出してください。私はそれを喜んで受け入れます。

私は私の質問の中で参照し、私は次善のだと思う私の現在のソリューションは、pages/index.jsでトップレベルの再利用可能なコンポーネントに必要なすべてのデータを構築することである(またはどこでもcreatePage({path, component, context})を使用してcontextにデータを注入します。このpathContextプロパティ経由componentコンストラクタで使用できるようになります。名前、pathContextは、私は、これは、このオブジェクトの精神の乱用だと思いますが、それは仕事を取得します。

たとえば、あなたはそのエントリがブログを持っていた場合タグの配列を持つ可能性があります。gatsby-node.js

const path = require('path'); 

const getUniqueTags = edges => { 
    const set = new Set(); 

    edges.forEach(edge => edge.node.frontmatter.tags.forEach(tag => set.add(tag))); 

    return [...set]; 
}; 

exports.createPages = ({ graphql, boundActionCreators }) => resolve(graphql(` 
     query AllPagesQuery { 
      allMarkdownRemark { 
       edges { 
        node { 
         frontmatter { 
          path 
          tags 
         } 
        } 
       } 
      } 
     } 
    `))) 
    .then(({ errors, data }) => { 
     const { createPage } = boundActionCreators; 
     const pageTemplate = path.resolve('./src/templates/page.js'); 

     if (errors) return Promise.reject(errors); 

     return data.allMarkdownRemark.edges.forEach(edge => { 
      createPage({ 
       path: edge.node.frontmatter.path, 
       component: pageTemplate, 
       context: { 
        path: edge.node.frontmatter.path, 
        tags: getUniqueTags(data.allMarkdownRemark.edges) 
       } 
      }); 
     }); 
    }) 
    .catch(err => console.log(err)); 

次に、あなたのtemplates/page.jsは、このようなユニークなタグ配列受け取ることができます:あなたはあなたのレイアウト/ index.js

export const avatarsFragmentQuery = graphql` 
    fragment avatars on RootQueryType { 
    avatars: allImageSharp { 
     edges { 
     node { 
      id 

     } 
     } 
    } 
    } 
` 

にフラグメントのクエリを作成し、あなたのページでそれを使用することができます

const IndexPage = ({ pathContext }) => { 
    const { tags } = pathContext.map(tag => <li>{ tag }</li>); 

    return <div>{ tags }</div>; 
}; 

export default IndexPage; 
+0

私は同じ方法を実装しています。この方法で危険がある場合や、同じ結果を達成するためにどのようにフラグメントを使用するかを説明することができれば、@ KyleMathewsからは素晴らしいことです。 – serby

+0

あなたのデータモデルを見ることなく(またはソースプラグインを知って)もっと知るのは難しいですが、理想的には各ページコンポーネントの 'pageQuery'を介して直接GraphQLのすべてのタグを取得します。これは一般的なアプローチhttps:// githubを示しています。com/gatsbyjs/gatsby/blob/master/docs/docs/building-with-components.md#page-template-components – chmac

2

を:

export const pageQuery = graphql` 
    query BlogQuery { 
    site { 
     siteMetadata { 
     title 
     } 
    } 

    ...avatars 
    } 
` 
関連する問題