2017-03-02 19 views
5

Reactフロントエンドを構築しています。静的クエリのリストから「アクティブ」クエリを選択し、結果をテーブルに表示するために平坦化します。 GraphQLクエリを上位コンポーネントからネストされた子コンポーネントに渡す最も良い方法は何ですか?ApolloクライアントでReactコンポーネントのGraphQLクエリを動的に設定する

私が見たドキュメント/ソリューションの多くは、静的なクエリをコンポーネント状態からコンポーネントに動的にバインドすることに焦点を当てていますが、これはさまざまな静的なクエリがさまざまなフィールドと異なるノードタイプ。

ここでは、ベストプラクティス/推奨アプローチは何ですか?私はこれが非常にユニークなユースケースではないように感じますが、私は似たようなことをする例は見つけられないようです。

私はクライアントサイドストアとしてApollo-Client/Reduxを使用しています。

class GridViewPage extends React.Component{ 
 
    constructor(props, context) { 
 
    super(props, context); 
 
    this.state = { 
 
     activeQuery = ... Stores the selected query ... 
 
    }; 
 
    } 
 

 
    render() { 
 
    return (
 
     <div className="gridContainer"> 
 
     ...Component here allows users to select a query from active list and saves it/it's ID/Index to the state... 
 

 
     <Panel collapsible> 
 
     ...Some toolbar components... 
 
     </Panel> 
 
     ...Component here displays the result of the query (Ideally by receiving the query or the result of as a prop?)... 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
GridViewPage.propTypes = { 
 
    grids: PropTypes.array.isRequired, 
 
    actions: PropTypes.object.isRequired 
 
}; 
 

 
function mapStateToProps(state, ownProps) { 
 
    return { 
 
     // Receives list of available queries as a prop 
 
     grids: state.grids 
 
    }; 
 
}

答えて

2

のは、例えば、以下のコンポーネントを見てみましょう:

ProfileWithData.js

import React, { Component, PropTypes } from 'react'; 
import { graphql } from 'react-apollo'; 
import gql from 'graphql-tag'; 

class Profile extends Component { ... } 
Profile.propTypes = { 
    data: PropTypes.shape({ 
    loading: PropTypes.bool.isRequired, 
    currentUser: PropTypes.object, 
    }).isRequired, 
}; 

// We use the gql tag to parse our query string into a query document 
const CurrentUserForLayout = gql` 
    query CurrentUserForLayout { 
    currentUser { 
     login 
     avatar_url 
    } 
    } 
`; 

const ProfileWithData = graphql(CurrentUserForLayout)(Profile); 

以下のコンポーネントの大まかな概要は

それは非常に簡単にhigher order componentとそれを包むことになります。

Profile.js

import React, { Component, PropTypes } from 'react'; 

export class Profile extends Component { ... } 
Profile.propTypes = { 
    data: PropTypes.shape({ 
    loading: PropTypes.bool.isRequired, 
    currentUser: PropTypes.object, 
    }).isRequired, 
}; 

createProfileWithData.js

import React, { Component, PropTypes } from 'react'; 
import { graphql } from 'react-apollo'; 
import { Profile } from './Profile' 

export default function createProfileWithData(query) => { 
    return graphql(query)(Profile); 
} 

あなたは、このようにそれを使用します。

Page.js

import React, { Component, PropTypes } from 'react'; 
import gql from 'graphql-tag'; 
import createProfileWithData from './createProfileWithData'; 

class Page extends Component { 

    renderProfileWithData() { 

     const { textQuery } = this.props; 
     // Simplest way, though you can call gql as a function too 
     const graphQLQuery = gql`${textQuery}`; 

     const profileWithDataType = createProfileWithData(graphQLQuery); 

     return (
     <profileWithDataType /> 
    ); 
    } 

    render() { 

    return (<div> 
       .. 
       {this.renderProfileWithData()} 
       .. 
      </div>) 
    } 

} 

Profile.propTypes = { 
    textQuery: PropTypes.string.isRequired, 
}; 

あなたはポイントを得ると思います。

もちろん、プロファイルはprops.data.currentUserを受け取っていませんが、ルートクエリによってはprops.data.*となり、内容によっては適切に処理します。

ノート:これはStack Overflowで直接書かれているので、問題が発生した場合はlmkと修正します。

+0

ありがとうございます!このパターンをプロジェクトに適用し始めました。私はそれが最終的にはうまくいくと思っています。私が直面しているエラーの1つは、 'const profileWithDataType = createProfileWithData(graphQLQuery);' は関数型を返すため、 '{this.renderProfileWithData()}'の内部にネストされたときに 'render()'関数にヒットしませんか? これは私のコードの構文上の問題かもしれませんが、言及する価値があると考えられました。 – Mike

+0

ええ、それはJSXの問題かもしれません。私はその構文が有効かどうか常に忘れています。あなたもできる: '' ' 返すReact.createElement(profileWithDataType、{}); '' ' 私はこれで既にこれを解決していると確信していますので、アップデートがうまくいくでしょう:) – advance512

+0

ちょっと!実際には、私はcreateProfileWithData.jsをスキップして、 'graphql(query)(Profile)'に相当するものでPage.jsのページに直接設定しました。 – Mike

関連する問題