Reputation: 422
I have the following getStaticProps() function in my pages/index.tsx file to fetch data from a GraphQL and this works fine.
export async function getStaticProps()
{
const client = new ApolloClient({
uri: "https://my-graphql-domain.com/graphql",
cache: new InMemoryCache(),
});
const { data } = await client.query({
query: gql`
query {
page(id:"1") {
data {
id
attributes{
Title
Builder {
__typename
...on ComponentWebBody {
ContentBlock1
ContentBlock2
}
}
}
}
}
}
`,
});
return {
props: {
data: data,
},
};
}
But I don't want to code in the client and query on every page, I would like to put it in the graphql/queries folder so I can call it on other pages.
Following a different tutorial that shows how to do this, I can also get the following to work when this is in a component file:
const { loading, error, data } = useFetchHomeContentQuery();
BUT when I add this into getStaticProps() I get the following error:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
The error occurs in my api.tsx for the graphql:
return Apollo.useQuery<FetchHomeContentQuery, FetchHomeContentQueryVariables>(FetchHomeContentDocument, options);
Upvotes: 0
Views: 1012
Reputation: 376
If you want to query inside getStaticProps then you can use like this
// pages/index.js
import { gql } from "@apollo/client";
import client from "../apollo-client";
// pages/index.js
export async function getStaticProps() {
const { data } = await client.query({
query: gql`
query Countries {
countries {
code
name
emoji
}
}
`,
});
return {
props: {
countries: data.countries.slice(0, 4),
},
};
}
But if you use hooks then it will work only in components, not on page.
// components/Countries.js
import { useQuery, gql } from "@apollo/client";
import styles from "../styles/Home.module.css";
const QUERY = gql`
query Countries {
countries {
code
name
emoji
}
}
`;
export default function Countries() {
const { data, loading, error } = useQuery(QUERY);
if (loading) {
return <h2><a href="#loading" aria-hidden="true" class="aal_anchor" id="loading"><svg aria-hidden="true" class="aal_svg" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loading...</h2>;
}
if (error) {
console.error(error);
return null;
}
const countries = data.countries.slice(0, 4);
return (
<div className={styles.grid}>
{countries.map((country) => (
<div key={country.code} className={styles.card}>
<h3><a href="#country-name" aria-hidden="true" class="aal_anchor" id="country-name"><svg aria-hidden="true" class="aal_svg" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>{country.name}</h3>
<p>
{country.code} - {country.emoji}
</p>
</div>
))}
</div>
);
}
Please check this tutorial for reference.
https://www.apollographql.com/blog/apollo-client/next-js/next-js-getting-started/
Upvotes: 1