Dynamically set GraphQL queries for React components with Apollo Client

I am creating a front-end React that allows users to select an β€œactive” query from a list of static queries and aligns with the result that will be displayed in the table. What is the best way to pass a GraphQL query from a higher order component to a nested child component?

Most of the documents / solutions I've seen focus on linking a static request with dynamic conditions from component states to component, which will not work for my purpose, since different static requests have different fields and request different node types.

What is the best practical / recommended approach? I feel that this is not a very unique use case, but I cannot find examples that would do something like this.

I use Apollo-Client / Redux as client-side storage.

The following is a rough outline of the component:

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 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 }; } 
+5
source share
1 answer

Take for example the following component:

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); 

It would be easy to wrap its component of a higher order :

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); } 

Then you will use it as follows:

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, }; 

I think you get the point.

Of course, your profile did not receive props.data.currentUser , rather, it will be props.data.* Depending on the root queries, and you will process it accordingly depending on the content.

Note : this was written directly in Stack Overflow, so if you have any problems - lmk, and I will fix it.

+2
source

Source: https://habr.com/ru/post/1264926/


All Articles