We were facing some problems with our own HOC we've written. This HOC does nothing special except to wrap a Component with graphql(). The only special was that depending on the props (from router) the Query changes. The problem here is now that wrapping the component with a new graphql() (so creating a new component) will cause remounting of the Component.
I know that there is a way to pass parameters dynamically based on the properties down to the query but in our case we need to execute different queries based on the props. Example:
// ...
const query = BuildQueryBasedOnProps(this.props);
ComponentWithApollo = graphql(gql(BuildQueryBasedOnProps))(ComponentToWrap);
// ...
return (
<ComponentWithApollo
{...this.props}
/>
);
So in our case we need to execute sometimes the query
query myQuery {
getPerson() {}
}
and sometimes
query mySecondQuery {
getAnimal() {}
}
.
So we were now thinking of wrapping our Component multiple times with graphql with any possible query. But how to tell graphql if it should execute it or if not ? Is there a way ? Something like:
export default compose(
graphql(QUERY_GET_PERSON, {
execute(props) {
return props.doPerson;
}
}),
graphql(QUERY_GET_ANIMAL, {
execute(props) {
return props.doAnimal;
}
})
)(MyApp);
Or maybe our thoughts about this issues are going into a wrong direction ? Is there a recommended way to create dynamic queries without "re-wrapping" the connected component ?
Version
@TimoRuetten why did you close this?
Well, this was closed but Ill reply anyway in case someone stumbles upon this.
You can actually write a skip condition in yout graphql() second argument.
const ProfileWithData = graphql(CurrentUserForLayout, {
skip: (ownProps) => !ownProps.authenticated,
})(Profile);
Apollo documentation:
https://www.apollographql.com/docs/react/basics/queries.html#graphql-skip
The skip is not what the first issue asks.
Something like this?
// @flow
import React from 'react'
import gql from 'graphql-tag'
import { getModelFields } from 'preset/utils'
const withItemQuery = (WrappedComponent: any) => (props: any) => {
const { model: { fields, itemQueryName } } = props
const query = gql(`
query ${itemQueryName}($id: ID!) {
item: ${itemQueryName}(id: $id) ${getModelFields(fields)}
}
`)
return (
<WrappedComponent
itemQuery={query}
itemQueryName={itemQueryName}
{...props}
/>
)
}
export default withItemQuery
I wanted to do this exact same thing, so I open sourced a simple function that handles this.
https://www.npmjs.com/package/react-apollo-dynamic-query
Hilariously enough, I wrote the documentation before seeing @TimoRuetten's original comment, but they both go through the same scenario of getting a "person" and an "animal".
I found using the @include and @skip directives solved this for me. https://graphql.org/learn/queries/#directives
Most helpful comment
Something like this?