FROM CACHE - en_header

Question with Querying with React/GraphQL/Apollo

LePong
Excursionist
25 1 17

Hi all!

I'm diving into developing an app for our store to be used internally. I'm learning everything involved as I go, i.e. I don't have react experience, nor any of the rest of the technologies being used for the app.

I have a laundry list of questions that I'm passing through our shopify rep to see if he can answer first, and anything else I will have to ask the forum here. But the big issue I'm currently facing is this:

(Please bear in mind that I don't have much experience so I'm not even sure where this issue lies, if it's react/apollo or graphql related)

 

I have a state that I pass down to children components. In that state is the value of a <Select> component that is being rendered in the child. That <Select> is also getting it's options through a graphql <Query>. The options won't change throughout the use of the app. So ideally, I would like to run the Query in the constructor, store the options return data, and just use that in the render of the Select.

But it looks like I can't run a GQL query without rendering a return, i.e. having it in the render(). I thought about running it once, but gated behind a bool. So after it runs once, set the bool to true and it'll never run/render again. But I figure there may be a better/cleaner way to do it. 

Any help would be greatly appreciated. Below is a simplified example of my components.

 

Parent:

state = {
    selectedOption: ""
};

render() {
    return (
        <Layout.AnnotatedSection
            title="Title"
        >
            <Card sectioned>
                <FormLayout>
                    <Child selectedOption={ this.state.selectedOption } />
                </FormLayout>
            </Card>
        </Layout.AnnotatedSection>
    );
}

 

Child:

const GET_PRODUCT_TYPES_QUERY = gql`
    query productTypes($count: Int!) {
        shop {
            productTypes(first: $count){
               edges{
                    node
                }
            }
        }
    }
`;

render() {
return(
<Query query={ GET_PRODUCT_TYPES_QUERY } variables={ { count: 10 } }>
{ ({ data, loading, error }) => {
if (loading) return <Loading />
if (error) return <div>{ error.message }</div>
const { edges } = data.shop.productTypes;
return (
<Select label="Product Type"
value={ this.props.selectedOption}
options={
edges.map(edge => ({
label: edge.node,
value: edge.node,
}))
}
>
</Select>
);
} }
</Query>
);
}

 

Replies 2 (2)
Marslan
Shopify Partner
44 4 13

Haven't actually dealt with Apollo but when you need to fetch data once per life cycle like in your case it is done in componentDidMount method in react. There is a great example here. But it uses Axios instead of Apollo, hope it helps.

Need some help or work done? Hire me!
LePong
Excursionist
25 1 17

Hey thanks for the reply.

 

Yeah that's my ideal solution, i.e. putting it in the ctor or the component did mount method, but I can't seem to find a way to run the query without rendering a result. I've put the query in the ctor and just returned a string, but it doesn't get into the Query. Again, not sure if it's an apollo or gql issue (I'm still trying to figure out where one technology begins and one ends)