From bca932f82c6b9f861b204dbaec11cc8513912355 Mon Sep 17 00:00:00 2001 From: amit Date: Fri, 5 Jul 2024 13:08:12 +0530 Subject: [PATCH 1/5] doc(graphql): graphql react --- graphql/graphql-react-client.md | 293 ++++++++++++++++++++++++++++++++ graphql/sidebar.ts | 1 + 2 files changed, 294 insertions(+) create mode 100644 graphql/graphql-react-client.md diff --git a/graphql/graphql-react-client.md b/graphql/graphql-react-client.md new file mode 100644 index 000000000..c8bd1783f --- /dev/null +++ b/graphql/graphql-react-client.md @@ -0,0 +1,293 @@ +--- +title: "GraphQL in React: 5 Best Approaches for Data Fetching." +description: "Apollo Client and Urql provide comprehensive solutions for large-scale applications, while the React Query combinations offer more flexibility." +sidebar_label: "GraphQL with React" +slug: graphql-react-client +--- + +## Introduction: +React developers often need to fetch data from GraphQL APIs, but with so many options available, choosing the right approach can be challenging. This comprehensive guide explores five effective methods for querying GraphQL data in React applications, ranging from full-featured client libraries to lightweight solutions. We'll use the SpaceX GraphQL API as an example to demonstrate how to fetch and display data about recent space missions. + +### 1. Apollo Client: The Comprehensive Solution + +Apollo Client stands out as the most feature-rich and widely adopted GraphQL library for React. It offers: + +- Robust data fetching capabilities +- Built-in caching mechanism +- Integrated state management + +#### Getting started with Apollo Client: + +1. Install dependencies: +``` +npm install @apollo/client graphql +``` + +2. Set up the Apollo Provider and client: + +```jsx +import { ApolloProvider, ApolloClient, InMemoryCache } from "@apollo/client"; + +const client = new ApolloClient({ + uri: "https://api.spacex.land/graphql/", + cache: new InMemoryCache() +}); + +ReactDOM.render( + + + , + rootElement +); +``` + +3. Use the `useQuery` hook to fetch data: + +```jsx +import { useQuery, gql } from "@apollo/client"; + +const LAUNCHES_QUERY = gql` + { + launchesPast(limit: 10) { + id + mission_name + } + } +`; + +function SpaceXLaunches() { + const { data, loading, error } = useQuery(LAUNCHES_QUERY); + + if (loading) return "Loading..."; + if (error) return
{error.message}
; + + return ( + + ); +} +``` + +### 2. Urql: The Lightweight Contender + +Urql offers a more streamlined alternative to Apollo, providing: + +- Smaller bundle size +- Simpler setup process +- Optional caching capabilities + +#### To use Urql: + +1. Install dependencies: +``` +npm install urql graphql +``` + +2. Set up the Urql Provider and client: + +```jsx +import { createClient, Provider } from 'urql'; + +const client = createClient({ + url: 'https://api.spacex.land/graphql/', +}); + +ReactDOM.render( + + + , + rootElement +); +``` + +3. Implement data fetching with the `useQuery` hook: + +```jsx +import { useQuery } from 'urql'; + +const LAUNCHES_QUERY = ` + { + launchesPast(limit: 10) { + id + mission_name + } + } +`; + +function SpaceXLaunches() { + const [result] = useQuery({ query: LAUNCHES_QUERY }); + const { data, fetching, error } = result; + + if (fetching) return "Loading..."; + if (error) return
{error.message}
; + + return ( + + ); +} +``` + +### 3. React Query + GraphQL Request: The Flexible Duo + +This combination offers a lightweight GraphQL client paired with a powerful data-fetching and state management library: + +1. Install dependencies: +``` +npm install react-query graphql-request +``` + +2. Set up React Query's QueryClientProvider: + +```jsx +import { QueryClient, QueryClientProvider } from "react-query"; + +const queryClient = new QueryClient(); + +ReactDOM.render( + + + , + rootElement +); +``` + +3. Implement data fetching: + +```jsx +import { request, gql } from "graphql-request"; +import { useQuery } from "react-query"; + +const endpoint = "https://api.spacex.land/graphql/"; +const LAUNCHES_QUERY = gql` + { + launchesPast(limit: 10) { + id + mission_name + } + } +`; + +function SpaceXLaunches() { + const { data, isLoading, error } = useQuery("launches", () => + request(endpoint, LAUNCHES_QUERY) + ); + + if (isLoading) return "Loading..."; + if (error) return
{error.message}
; + + return ( + + ); +} +``` + +### 4. React Query + Axios: Leveraging a Popular HTTP Client + +This approach combines React Query with the widely-used Axios library: + +1. Install dependencies: +``` +npm install react-query axios +``` + +2. Implement data fetching: + +```jsx +import axios from "axios"; +import { useQuery } from "react-query"; + +const endpoint = "https://api.spacex.land/graphql/"; +const LAUNCHES_QUERY = ` + { + launchesPast(limit: 10) { + id + mission_name + } + } +`; + +function SpaceXLaunches() { + const { data, isLoading, error } = useQuery("launches", () => + axios.post(endpoint, { query: LAUNCHES_QUERY }) + .then(response => response.data.data) + ); + + if (isLoading) return "Loading..."; + if (error) return
{error.message}
; + + return ( + + ); +} +``` + +### 5. React Query + Fetch API: The Minimalist Approach + +This method utilizes the browser's built-in Fetch API alongside React Query: + +1. Install React Query: +``` +npm install react-query +``` + +2. Implement data fetching: + +```jsx +import { useQuery } from "react-query"; + +const endpoint = "https://api.spacex.land/graphql/"; +const LAUNCHES_QUERY = ` + { + launchesPast(limit: 10) { + id + mission_name + } + } +`; + +function SpaceXLaunches() { + const { data, isLoading, error } = useQuery("launches", () => + fetch(endpoint, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ query: LAUNCHES_QUERY }) + }) + .then(response => { + if (!response.ok) throw new Error("Network response was not ok"); + return response.json(); + }) + .then(result => result.data) + ); + + if (isLoading) return "Loading..."; + if (error) return
{error.message}
; + + return ( + + ); +} +``` + +## Conclusion: +Each of these five approaches to fetching GraphQL data in React offers its own set of advantages. Apollo Client and Urql provide comprehensive solutions for large-scale applications, while the React Query combinations offer more flexibility and lighter-weight options. Consider your project's specific needs, such as bundle size, caching requirements, and overall complexity, when choosing the best method for your application. + +By mastering these techniques, you'll be well-equipped to efficiently integrate GraphQL data fetching into your React projects, regardless of their scale or complexity. \ No newline at end of file diff --git a/graphql/sidebar.ts b/graphql/sidebar.ts index 84ede8ddf..13aa07ca3 100644 --- a/graphql/sidebar.ts +++ b/graphql/sidebar.ts @@ -12,6 +12,7 @@ const sidebars: SidebarsConfig = { label: "GraphQL Tutorial", items: ["what-is-graphql", "schema-and-types", "queries", "mutations", "variables", "fragments", "introspection"], }, + "graphql-react-client", ], } From 4c3237ea2d8165e9432ae1b047901b4b5072743f Mon Sep 17 00:00:00 2001 From: amit Date: Fri, 5 Jul 2024 13:39:31 +0530 Subject: [PATCH 2/5] doc(graphql): update --- graphql/graphql-react-client.md | 523 ++++++++++++++++---------------- 1 file changed, 254 insertions(+), 269 deletions(-) diff --git a/graphql/graphql-react-client.md b/graphql/graphql-react-client.md index c8bd1783f..5335a0b6d 100644 --- a/graphql/graphql-react-client.md +++ b/graphql/graphql-react-client.md @@ -6,288 +6,273 @@ slug: graphql-react-client --- ## Introduction: -React developers often need to fetch data from GraphQL APIs, but with so many options available, choosing the right approach can be challenging. This comprehensive guide explores five effective methods for querying GraphQL data in React applications, ranging from full-featured client libraries to lightweight solutions. We'll use the SpaceX GraphQL API as an example to demonstrate how to fetch and display data about recent space missions. +React developers often need to fetch data from GraphQL APIs. This comprehensive guide explores five effective methods for querying GraphQL data in React applications, using the SpaceX GraphQL API to demonstrate fetching and displaying data about recent space missions. We'll cover full-featured client libraries to lightweight solutions, providing a detailed comparison table and specific use cases for each method. ### 1. Apollo Client: The Comprehensive Solution - -Apollo Client stands out as the most feature-rich and widely adopted GraphQL library for React. It offers: - -- Robust data fetching capabilities -- Built-in caching mechanism -- Integrated state management +Apollo Client is the most feature-rich GraphQL library for React, widely adopted for its robust data fetching, built-in caching, and integrated state management. #### Getting started with Apollo Client: - -1. Install dependencies: -``` -npm install @apollo/client graphql -``` - -2. Set up the Apollo Provider and client: - -```jsx -import { ApolloProvider, ApolloClient, InMemoryCache } from "@apollo/client"; - -const client = new ApolloClient({ - uri: "https://api.spacex.land/graphql/", - cache: new InMemoryCache() -}); - -ReactDOM.render( - - - , - rootElement -); -``` - -3. Use the `useQuery` hook to fetch data: - -```jsx -import { useQuery, gql } from "@apollo/client"; - -const LAUNCHES_QUERY = gql` - { - launchesPast(limit: 10) { - id - mission_name - } - } -`; - -function SpaceXLaunches() { - const { data, loading, error } = useQuery(LAUNCHES_QUERY); - - if (loading) return "Loading..."; - if (error) return
{error.message}
; - - return ( - - ); -} -``` +1. **Install dependencies**: + ```bash + npm install @apollo/client graphql + ``` +2. **Set up the Apollo Provider and client**: + ```jsx + import { ApolloProvider, ApolloClient, InMemoryCache } from "@apollo/client"; + + const client = new ApolloClient({ + uri: "https://api.spacex.land/graphql/", + cache: new InMemoryCache() + }); + + ReactDOM.render( + + + , + rootElement + ); + ``` +3. **Use the `useQuery` hook to fetch data**: + ```jsx + import { useQuery, gql } from "@apollo/client"; + + const LAUNCHES_QUERY = gql` + { + launchesPast(limit: 10) { + id + mission_name + } + } + `; + + function SpaceXLaunches() { + const { data, loading, error } = useQuery(LAUNCHES_QUERY); + + if (loading) return "Loading..."; + if (error) return
{error.message}
; + + return ( + + ); + } + ``` ### 2. Urql: The Lightweight Contender - -Urql offers a more streamlined alternative to Apollo, providing: - -- Smaller bundle size -- Simpler setup process -- Optional caching capabilities +Urql provides a streamlined alternative to Apollo, with a smaller bundle size, simpler setup process, and optional caching. #### To use Urql: - -1. Install dependencies: -``` -npm install urql graphql -``` - -2. Set up the Urql Provider and client: - -```jsx -import { createClient, Provider } from 'urql'; - -const client = createClient({ - url: 'https://api.spacex.land/graphql/', -}); - -ReactDOM.render( - - - , - rootElement -); -``` - -3. Implement data fetching with the `useQuery` hook: - -```jsx -import { useQuery } from 'urql'; - -const LAUNCHES_QUERY = ` - { - launchesPast(limit: 10) { - id - mission_name - } - } -`; - -function SpaceXLaunches() { - const [result] = useQuery({ query: LAUNCHES_QUERY }); - const { data, fetching, error } = result; - - if (fetching) return "Loading..."; - if (error) return
{error.message}
; - - return ( - - ); -} -``` +1. **Install dependencies**: + ```bash + npm install urql graphql + ``` +2. **Set up the Urql Provider and client**: + ```jsx + import { createClient, Provider } from 'urql'; + + const client = createClient({ + url: 'https://api.spacex.land/graphql/', + }); + + ReactDOM.render( + + + , + rootElement + ); + ``` +3. **Implement data fetching with the `useQuery` hook**: + ```jsx + import { useQuery } from 'urql'; + + const LAUNCHES_QUERY = ` + { + launchesPast(limit: 10) { + id + mission_name + } + } + `; + + function SpaceXLaunches() { + const [result] = useQuery({ query: LAUNCHES_QUERY }); + const { data, fetching, error } = result; + + if (fetching) return "Loading..."; + if (error) return
{error.message}
; + + return ( + + ); + } + ``` ### 3. React Query + GraphQL Request: The Flexible Duo - -This combination offers a lightweight GraphQL client paired with a powerful data-fetching and state management library: - -1. Install dependencies: -``` -npm install react-query graphql-request -``` - -2. Set up React Query's QueryClientProvider: - -```jsx -import { QueryClient, QueryClientProvider } from "react-query"; - -const queryClient = new QueryClient(); - -ReactDOM.render( - - - , - rootElement -); -``` - -3. Implement data fetching: - -```jsx -import { request, gql } from "graphql-request"; -import { useQuery } from "react-query"; - -const endpoint = "https://api.spacex.land/graphql/"; -const LAUNCHES_QUERY = gql` - { - launchesPast(limit: 10) { - id - mission_name - } - } -`; - -function SpaceXLaunches() { - const { data, isLoading, error } = useQuery("launches", () => - request(endpoint, LAUNCHES_QUERY) - ); - - if (isLoading) return "Loading..."; - if (error) return
{error.message}
; - - return ( - - ); -} -``` +This combination pairs a lightweight GraphQL client with a powerful data-fetching library. + +1. **Install dependencies**: + ```bash + npm install react-query graphql-request + ``` +2. **Set up React Query's QueryClientProvider**: + ```jsx + import { QueryClient, QueryClientProvider } from "react-query"; + + const queryClient = new QueryClient(); + + ReactDOM.render( + + + , + rootElement + ); + ``` +3. **Implement data fetching**: + ```jsx + import { request, gql } from "graphql-request"; + import { useQuery } from "react-query"; + + const endpoint = "https://api.spacex.land/graphql/"; + const LAUNCHES_QUERY = gql` + { + launchesPast(limit: 10) { + id + mission_name + } + } + `; + + function SpaceXLaunches() { + const { data, isLoading, error } = useQuery("launches", () => + request(endpoint, LAUNCHES_QUERY) + ); + + if (isLoading) return "Loading..."; + if (error) return
{error.message}
; + + return ( + + ); + } + ``` ### 4. React Query + Axios: Leveraging a Popular HTTP Client - -This approach combines React Query with the widely-used Axios library: - -1. Install dependencies: -``` -npm install react-query axios -``` - -2. Implement data fetching: - -```jsx -import axios from "axios"; -import { useQuery } from "react-query"; - -const endpoint = "https://api.spacex.land/graphql/"; -const LAUNCHES_QUERY = ` - { - launchesPast(limit: 10) { - id - mission_name - } - } -`; - -function SpaceXLaunches() { - const { data, isLoading, error } = useQuery("launches", () => - axios.post(endpoint, { query: LAUNCHES_QUERY }) - .then(response => response.data.data) - ); - - if (isLoading) return "Loading..."; - if (error) return
{error.message}
; - - return ( - - ); -} -``` +Combines React Query with Axios for familiar HTTP handling. + +1. **Install dependencies**: + ```bash + npm install react-query axios + ``` +2. **Implement data fetching**: + ```jsx + import axios from "axios"; + import { useQuery } from "react-query"; + + const endpoint = "https://api.spacex.land/graphql/"; + const LAUNCHES_QUERY = ` + { + launchesPast(limit: 10) { + id + mission_name + } + } + `; + + function SpaceXLaunches() { + const { data, isLoading, error } = useQuery("launches", () => + axios.post(endpoint, { query: LAUNCHES_QUERY }) + .then(response => response.data.data) + ); + + if (isLoading) return "Loading..."; + if (error) return
{error.message}
; + + return ( + + ); + } + ``` ### 5. React Query + Fetch API: The Minimalist Approach - -This method utilizes the browser's built-in Fetch API alongside React Query: - -1. Install React Query: -``` -npm install react-query -``` - -2. Implement data fetching: - -```jsx -import { useQuery } from "react-query"; - -const endpoint = "https://api.spacex.land/graphql/"; -const LAUNCHES_QUERY = ` - { - launchesPast(limit: 10) { - id - mission_name - } - } -`; - -function SpaceXLaunches() { - const { data, isLoading, error } = useQuery("launches", () => - fetch(endpoint, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ query: LAUNCHES_QUERY }) - }) - .then(response => { - if (!response.ok) throw new Error("Network response was not ok"); - return response.json(); - }) - .then(result => result.data) - ); - - if (isLoading) return "Loading..."; - if (error) return
{error.message}
; - - return ( - - ); -} -``` +Utilizes the browser's Fetch API with React Query for a minimalistic approach. + +1. **Install React Query**: + ```bash + npm install react-query + ``` +2. **Implement data fetching**: + ```jsx + import { useQuery } from "react-query"; + + const endpoint = "https://api.spacex.land/graphql/"; + const LAUNCHES_QUERY = ` + { + launchesPast(limit: 10) { + id + mission_name + } + } + `; + + function SpaceXLaunches() { + the { data, isLoading, error } = useQuery("launches", () => + fetch(endpoint, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ query: LAUNCHES_QUERY }) + }) + .then(response => { + if (!response.ok) throw new Error("Network response was not ok"); + return response.json(); + }) + .then(result => result.data) + ); + + if (isLoading) return "Loading..."; + if (error) return
{error.message}
; + + return ( + + ); + } + ``` + +## Detailed Comparison Table +Here’s a comparison table to help choose the right method based on specific needs: + +| Method | Bundle Size | Learning Curve | Caching Capabilities | Community Support | Additional Features | +|--------------------------------|-------------|----------------|----------------------|-------------------|------------------------------------------| +| Apollo Client | _ | Moderate | Extensive | High | State management, optimistic UI updates | +| Urql | _ | Low | Moderate | Moderate | Extensible architecture | +| React Query + GraphQL Request | _ | Low | _ | Growing | Minimal overhead | +| React Query + Axios | _ | Low | _ | High | Familiar HTTP handling | +| React Query + Fetch API | _ | Low | _ | Moderate | Browser-native, minimal setup | + +### Use Cases for Each Method +- **Apollo Client**: Best for large-scale applications needing complex state management and data synchronization. +- **Urql**: Suitable for medium-sized projects where simplicity and performance are prioritized. +- **React Query + GraphQL Request**: Ideal for projects requiring high flexibility with minimal GraphQL-specific setup. +- **React Query + Axios**: Preferred when developers are already familiar with Axios and need robust HTTP capabilities. +- **React Query + Fetch API**: Optimal for projects that require a minimalistic approach with no additional dependencies. ## Conclusion: -Each of these five approaches to fetching GraphQL data in React offers its own set of advantages. Apollo Client and Urql provide comprehensive solutions for large-scale applications, while the React Query combinations offer more flexibility and lighter-weight options. Consider your project's specific needs, such as bundle size, caching requirements, and overall complexity, when choosing the best method for your application. - -By mastering these techniques, you'll be well-equipped to efficiently integrate GraphQL data fetching into your React projects, regardless of their scale or complexity. \ No newline at end of file +By understanding the distinct features and use cases of each method, developers can select the most appropriate GraphQL fetching technique for their React projects. This guide aims to equip developers with the knowledge to efficiently integrate GraphQL data fetching into their applications, regardless of scale or complexity. \ No newline at end of file From 994ae15e5a31d0fa91ed2761f28f191712627477 Mon Sep 17 00:00:00 2001 From: amit Date: Fri, 5 Jul 2024 13:40:53 +0530 Subject: [PATCH 3/5] doc(graphql): prettier --- graphql/graphql-react-client.md | 145 ++++++++++++++++++++------------ 1 file changed, 89 insertions(+), 56 deletions(-) diff --git a/graphql/graphql-react-client.md b/graphql/graphql-react-client.md index 5335a0b6d..1719d532e 100644 --- a/graphql/graphql-react-client.md +++ b/graphql/graphql-react-client.md @@ -6,35 +6,45 @@ slug: graphql-react-client --- ## Introduction: + React developers often need to fetch data from GraphQL APIs. This comprehensive guide explores five effective methods for querying GraphQL data in React applications, using the SpaceX GraphQL API to demonstrate fetching and displaying data about recent space missions. We'll cover full-featured client libraries to lightweight solutions, providing a detailed comparison table and specific use cases for each method. ### 1. Apollo Client: The Comprehensive Solution + Apollo Client is the most feature-rich GraphQL library for React, widely adopted for its robust data fetching, built-in caching, and integrated state management. #### Getting started with Apollo Client: + 1. **Install dependencies**: ```bash npm install @apollo/client graphql ``` 2. **Set up the Apollo Provider and client**: + ```jsx - import { ApolloProvider, ApolloClient, InMemoryCache } from "@apollo/client"; + import { + ApolloProvider, + ApolloClient, + InMemoryCache, + } from "@apollo/client" const client = new ApolloClient({ uri: "https://api.spacex.land/graphql/", - cache: new InMemoryCache() - }); + cache: new InMemoryCache(), + }) ReactDOM.render( , - rootElement - ); + rootElement, + ) ``` + 3. **Use the `useQuery` hook to fetch data**: + ```jsx - import { useQuery, gql } from "@apollo/client"; + import {useQuery, gql} from "@apollo/client" const LAUNCHES_QUERY = gql` { @@ -43,13 +53,13 @@ Apollo Client is the most feature-rich GraphQL library for React, widely adopted mission_name } } - `; + ` function SpaceXLaunches() { - const { data, loading, error } = useQuery(LAUNCHES_QUERY); + const {data, loading, error} = useQuery(LAUNCHES_QUERY) - if (loading) return "Loading..."; - if (error) return
{error.message}
; + if (loading) return "Loading..." + if (error) return
{error.message}
return (
    @@ -57,36 +67,41 @@ Apollo Client is the most feature-rich GraphQL library for React, widely adopted
  • {launch.mission_name}
  • ))}
- ); + ) } ``` ### 2. Urql: The Lightweight Contender + Urql provides a streamlined alternative to Apollo, with a smaller bundle size, simpler setup process, and optional caching. #### To use Urql: + 1. **Install dependencies**: ```bash npm install urql graphql ``` 2. **Set up the Urql Provider and client**: + ```jsx - import { createClient, Provider } from 'urql'; + import {createClient, Provider} from "urql" const client = createClient({ - url: 'https://api.spacex.land/graphql/', - }); + url: "https://api.spacex.land/graphql/", + }) ReactDOM.render( , - rootElement - ); + rootElement, + ) ``` + 3. **Implement data fetching with the `useQuery` hook**: + ```jsx - import { useQuery } from 'urql'; + import {useQuery} from "urql" const LAUNCHES_QUERY = ` { @@ -95,14 +110,14 @@ Urql provides a streamlined alternative to Apollo, with a smaller bundle size, s mission_name } } - `; + ` function SpaceXLaunches() { - const [result] = useQuery({ query: LAUNCHES_QUERY }); - const { data, fetching, error } = result; + const [result] = useQuery({query: LAUNCHES_QUERY}) + const {data, fetching, error} = result - if (fetching) return "Loading..."; - if (error) return
{error.message}
; + if (fetching) return "Loading..." + if (error) return
{error.message}
return (
    @@ -110,11 +125,12 @@ Urql provides a streamlined alternative to Apollo, with a smaller bundle size, s
  • {launch.mission_name}
  • ))}
- ); + ) } ``` ### 3. React Query + GraphQL Request: The Flexible Duo + This combination pairs a lightweight GraphQL client with a powerful data-fetching library. 1. **Install dependencies**: @@ -122,24 +138,30 @@ This combination pairs a lightweight GraphQL client with a powerful data-fetchin npm install react-query graphql-request ``` 2. **Set up React Query's QueryClientProvider**: + ```jsx - import { QueryClient, QueryClientProvider } from "react-query"; + import { + QueryClient, + QueryClientProvider, + } from "react-query" - const queryClient = new QueryClient(); + const queryClient = new QueryClient() ReactDOM.render( , - rootElement - ); + rootElement, + ) ``` + 3. **Implement data fetching**: + ```jsx - import { request, gql } from "graphql-request"; - import { useQuery } from "react-query"; + import {request, gql} from "graphql-request" + import {useQuery} from "react-query" - const endpoint = "https://api.spacex.land/graphql/"; + const endpoint = "https://api.spacex.land/graphql/" const LAUNCHES_QUERY = gql` { launchesPast(limit: 10) { @@ -147,15 +169,16 @@ This combination pairs a lightweight GraphQL client with a powerful data-fetchin mission_name } } - `; + ` function SpaceXLaunches() { - const { data, isLoading, error } = useQuery("launches", () => - request(endpoint, LAUNCHES_QUERY) - ); + const {data, isLoading, error} = useQuery( + "launches", + () => request(endpoint, LAUNCHES_QUERY), + ) - if (isLoading) return "Loading..."; - if (error) return
{error.message}
; + if (isLoading) return "Loading..." + if (error) return
{error.message}
return (
    @@ -163,11 +186,12 @@ This combination pairs a lightweight GraphQL client with a powerful data-fetchin
  • {launch.mission_name}
  • ))}
- ); + ) } ``` ### 4. React Query + Axios: Leveraging a Popular HTTP Client + Combines React Query with Axios for familiar HTTP handling. 1. **Install dependencies**: @@ -175,11 +199,12 @@ Combines React Query with Axios for familiar HTTP handling. npm install react-query axios ``` 2. **Implement data fetching**: + ```jsx - import axios from "axios"; - import { useQuery } from "react-query"; + import axios from "axios" + import {useQuery} from "react-query" - const endpoint = "https://api.spacex.land/graphql/"; + const endpoint = "https://api.spacex.land/graphql/" const LAUNCHES_QUERY = ` { launchesPast(limit: 10) { @@ -187,16 +212,19 @@ Combines React Query with Axios for familiar HTTP handling. mission_name } } - `; + ` function SpaceXLaunches() { - const { data, isLoading, error } = useQuery("launches", () => - axios.post(endpoint, { query: LAUNCHES_QUERY }) - .then(response => response.data.data) - ); + const {data, isLoading, error} = useQuery( + "launches", + () => + axios + .post(endpoint, {query: LAUNCHES_QUERY}) + .then((response) => response.data.data), + ) - if (isLoading) return "Loading..."; - if (error) return
{error.message}
; + if (isLoading) return "Loading..." + if (error) return
{error.message}
return (
    @@ -204,11 +232,12 @@ Combines React Query with Axios for familiar HTTP handling.
  • {launch.mission_name}
  • ))}
- ); + ) } ``` ### 5. React Query + Fetch API: The Minimalist Approach + Utilizes the browser's Fetch API with React Query for a minimalistic approach. 1. **Install React Query**: @@ -216,6 +245,7 @@ Utilizes the browser's Fetch API with React Query for a minimalistic approach. npm install react-query ``` 2. **Implement data fetching**: + ```jsx import { useQuery } from "react-query"; @@ -257,17 +287,19 @@ Utilizes the browser's Fetch API with React Query for a minimalistic approach. ``` ## Detailed Comparison Table + Here’s a comparison table to help choose the right method based on specific needs: -| Method | Bundle Size | Learning Curve | Caching Capabilities | Community Support | Additional Features | -|--------------------------------|-------------|----------------|----------------------|-------------------|------------------------------------------| -| Apollo Client | _ | Moderate | Extensive | High | State management, optimistic UI updates | -| Urql | _ | Low | Moderate | Moderate | Extensible architecture | -| React Query + GraphQL Request | _ | Low | _ | Growing | Minimal overhead | -| React Query + Axios | _ | Low | _ | High | Familiar HTTP handling | -| React Query + Fetch API | _ | Low | _ | Moderate | Browser-native, minimal setup | +| Method | Bundle Size | Learning Curve | Caching Capabilities | Community Support | Additional Features | +| ----------------------------- | ----------- | -------------- | -------------------- | ----------------- | --------------------------------------- | +| Apollo Client | \_ | Moderate | Extensive | High | State management, optimistic UI updates | +| Urql | \_ | Low | Moderate | Moderate | Extensible architecture | +| React Query + GraphQL Request | \_ | Low | \_ | Growing | Minimal overhead | +| React Query + Axios | \_ | Low | \_ | High | Familiar HTTP handling | +| React Query + Fetch API | \_ | Low | \_ | Moderate | Browser-native, minimal setup | ### Use Cases for Each Method + - **Apollo Client**: Best for large-scale applications needing complex state management and data synchronization. - **Urql**: Suitable for medium-sized projects where simplicity and performance are prioritized. - **React Query + GraphQL Request**: Ideal for projects requiring high flexibility with minimal GraphQL-specific setup. @@ -275,4 +307,5 @@ Here’s a comparison table to help choose the right method based on specific ne - **React Query + Fetch API**: Optimal for projects that require a minimalistic approach with no additional dependencies. ## Conclusion: -By understanding the distinct features and use cases of each method, developers can select the most appropriate GraphQL fetching technique for their React projects. This guide aims to equip developers with the knowledge to efficiently integrate GraphQL data fetching into their applications, regardless of scale or complexity. \ No newline at end of file + +By understanding the distinct features and use cases of each method, developers can select the most appropriate GraphQL fetching technique for their React projects. This guide aims to equip developers with the knowledge to efficiently integrate GraphQL data fetching into their applications, regardless of scale or complexity. From 1d91ae1e9331b3cf085c96e11e572fb47d0ee477 Mon Sep 17 00:00:00 2001 From: David Anyatonwu Date: Fri, 5 Jul 2024 15:56:54 +0100 Subject: [PATCH 4/5] docs: Add caching and error handling sections based on #308 --- graphql/graphql-react-client.md | 285 ++++++++++++++++++++++++++++++-- 1 file changed, 274 insertions(+), 11 deletions(-) diff --git a/graphql/graphql-react-client.md b/graphql/graphql-react-client.md index 1719d532e..520a2c254 100644 --- a/graphql/graphql-react-client.md +++ b/graphql/graphql-react-client.md @@ -5,7 +5,7 @@ sidebar_label: "GraphQL with React" slug: graphql-react-client --- -## Introduction: +## Introduction React developers often need to fetch data from GraphQL APIs. This comprehensive guide explores five effective methods for querying GraphQL data in React applications, using the SpaceX GraphQL API to demonstrate fetching and displaying data about recent space missions. We'll cover full-featured client libraries to lightweight solutions, providing a detailed comparison table and specific use cases for each method. @@ -13,12 +13,14 @@ React developers often need to fetch data from GraphQL APIs. This comprehensive Apollo Client is the most feature-rich GraphQL library for React, widely adopted for its robust data fetching, built-in caching, and integrated state management. -#### Getting started with Apollo Client: +#### Getting started with Apollo Client 1. **Install dependencies**: + ```bash npm install @apollo/client graphql ``` + 2. **Set up the Apollo Provider and client**: ```jsx @@ -75,12 +77,14 @@ Apollo Client is the most feature-rich GraphQL library for React, widely adopted Urql provides a streamlined alternative to Apollo, with a smaller bundle size, simpler setup process, and optional caching. -#### To use Urql: +#### To use Urql 1. **Install dependencies**: + ```bash npm install urql graphql ``` + 2. **Set up the Urql Provider and client**: ```jsx @@ -134,9 +138,11 @@ Urql provides a streamlined alternative to Apollo, with a smaller bundle size, s This combination pairs a lightweight GraphQL client with a powerful data-fetching library. 1. **Install dependencies**: + ```bash npm install react-query graphql-request ``` + 2. **Set up React Query's QueryClientProvider**: ```jsx @@ -195,9 +201,11 @@ This combination pairs a lightweight GraphQL client with a powerful data-fetchin Combines React Query with Axios for familiar HTTP handling. 1. **Install dependencies**: + ```bash npm install react-query axios ``` + 2. **Implement data fetching**: ```jsx @@ -241,9 +249,11 @@ Combines React Query with Axios for familiar HTTP handling. Utilizes the browser's Fetch API with React Query for a minimalistic approach. 1. **Install React Query**: + ```bash npm install react-query ``` + 2. **Implement data fetching**: ```jsx @@ -290,13 +300,266 @@ Utilizes the browser's Fetch API with React Query for a minimalistic approach. Here’s a comparison table to help choose the right method based on specific needs: -| Method | Bundle Size | Learning Curve | Caching Capabilities | Community Support | Additional Features | -| ----------------------------- | ----------- | -------------- | -------------------- | ----------------- | --------------------------------------- | -| Apollo Client | \_ | Moderate | Extensive | High | State management, optimistic UI updates | -| Urql | \_ | Low | Moderate | Moderate | Extensible architecture | -| React Query + GraphQL Request | \_ | Low | \_ | Growing | Minimal overhead | -| React Query + Axios | \_ | Low | \_ | High | Familiar HTTP handling | -| React Query + Fetch API | \_ | Low | \_ | Moderate | Browser-native, minimal setup | + +| Method | Bundle Size (minified + gzip)* | Learning Curve | Caching Capabilities | Community Support | Additional Features | +| ----------------------------- | ----------------------------- | -------------- | ------------------------------------------- | ----------------- | --------------------------------------- | +| Apollo Client | ~47.04 KB | Moderate | Extensive (InMemoryCache, customizable) | High | State management, optimistic UI updates | +| Urql | ~2.18 KB | Low | Moderate (Document caching) | Moderate | Extensible architecture | +| React Query + GraphQL Request | ~13 KB + ~185.8 KB | Low | Basic (Managed by React Query) | Growing | Minimal overhead | +| React Query + Axios | ~13 KB + ~13.2 KB | Low | Basic (Managed by React Query) | High | Familiar HTTP handling | +| React Query + Fetch API | ~13 KB + ~152.4 KB | Low | Basic (Managed by React Query) | Moderate | Browser-native, minimal setup | + +(*) culled from *bundlephobia.com* + +### Caching Capabilities + +1. **Apollo Client**: + - Normalized caching (stores entities by ID) + - Automatic cache updates + - Manual cache manipulation + - Persistence and rehydration + - Optimistic updates +2. **Urql**: + - Document caching (stores full query responses) + - Customizable caching with exchangers + - Persistence support +3. **React Query** (applies to all React Query combinations): + - Time-based caching + - Stale-while-revalidate strategy + - Manual cache manipulation + - Persistence and rehydration + +## Error Handling + +Proper error handling is crucial for creating robust GraphQL applications. This section provides a detailed discussion on error handling for each client, including code examples for different types of errors and guidance on displaying user-friendly error messages. + +### 1. Apollo Client + +Apollo Client provides detailed error information through the `error` property returned by the `useQuery` hook. It distinguishes between GraphQL errors and network errors. + +```jsx +import { useQuery, gql } from "@apollo/client"; + +const LAUNCHES_QUERY = gql` + { + launchesPast(limit: 10) { + id + mission_name + } + } +`; + +function SpaceXLaunches() { + const { data, loading, error } = useQuery(LAUNCHES_QUERY); + + if (loading) return "Loading..."; + if (error) { + return ; + } + + // Render data... +} + +function ErrorDisplay({ error }) { + // Function to generate a user-friendly error message + const getUserFriendlyErrorMessage = (error) => { + if (error.networkError) { + return "Unable to reach the server. Please check your internet connection and try again."; + } + if (error.graphQLErrors.length > 0) { + // You might want to customize this based on specific error codes or messages + return "There was an issue processing your request. Please try again later."; + } + return "An unexpected error occurred. Please try again."; + }; + + return ( +
+

Oops! Something went wrong

+

{getUserFriendlyErrorMessage(error)}

+ {process.env.NODE_ENV !== 'production' && ( +
+ Technical Details + {error.graphQLErrors.map(({ message, locations, path }, index) => ( +
+

GraphQL error: {message}

+

Location: {JSON.stringify(locations)}

+

Path: {JSON.stringify(path)}

+
+ ))} + {error.networkError && ( +

Network error: {error.networkError.message}

+ )} +
+ )} +
+ ); +} +``` + +This example demonstrates how to: + +- Display a user-friendly error message based on the type of error +- Show technical details only in non-production environments +- Handle both GraphQL and network errors + +### 2. Urql + +Urql provides error information through the `error` property in the result object. + +```tsx +import { useQuery } from "urql"; + +const LAUNCHES_QUERY = ` + { + launchesPast(limit: 10) { + id + mission_name + } + } +`; + +function SpaceXLaunches() { + const [result] = useQuery({ query: LAUNCHES_QUERY }); + const { data, fetching, error } = result; + + if (fetching) return "Loading..."; + if (error) { + return ; + } + + // Render data... +} + +function ErrorDisplay({ error }) { + const getUserFriendlyErrorMessage = (error) => { + if (error.networkError) { + return "Unable to reach the server. Please check your internet connection and try again."; + } + if (error.graphQLErrors.length > 0) { + // Customize based on specific error types if needed + return "There was an issue processing your request. Please try again later."; + } + return "An unexpected error occurred. Please try again."; + }; + + return ( +
+

Oops! Something went wrong

+

{getUserFriendlyErrorMessage(error)}

+ {process.env.NODE_ENV !== 'production' && ( +
+ Technical Details + {error.graphQLErrors.map((graphQLError, index) => ( +
+

GraphQL error: {graphQLError.message}

+ {graphQLError.locations && ( +

Location: {JSON.stringify(graphQLError.locations)}

+ )} + {graphQLError.path && ( +

Path: {JSON.stringify(graphQLError.path)}

+ )} +
+ ))} + {error.networkError && ( +

Network error: {error.networkError.message}

+ )} +
+ )} +
+ ); +} +``` + +### React Query (applies to all React Query examples) + +React Query provides error information through the `error` property returned by the `useQuery` hook. + +When using React Query with GraphQL Request, you need to handle errors from both libraries. This approach requires more manual error handling but offers fine-grained control. + +```tsx +import { useQuery } from "react-query"; +import { request, gql } from "graphql-request"; + +const endpoint = "https://api.spacex.land/graphql/"; +const LAUNCHES_QUERY = gql` + { + launchesPast(limit: 10) { + id + mission_name + } + } +`; + +function SpaceXLaunches() { + const { data, isLoading, error } = useQuery("launches", async () => { + try { + return await request(endpoint, LAUNCHES_QUERY); + } catch (error) { + // GraphQL Request wraps GraphQL errors in a ClientError + if (error.response) { + throw new Error(JSON.stringify(error.response.errors)); + } else { + // Network error + throw new Error(`Network error: ${error.message}`); + } + } + }); + + if (isLoading) return "Loading..."; + if (error) { + return ; + } + + // Render data... +} + +function ErrorDisplay({ error }) { + const getUserFriendlyErrorMessage = (error) => { + try { + const parsedError = JSON.parse(error.message); + if (Array.isArray(parsedError)) { + // GraphQL errors + return "There was an issue processing your request. Please try again later."; + } + } catch { + // Network error or other non-GraphQL error + return "Unable to reach the server. Please check your internet connection and try again."; + } + return "An unexpected error occurred. Please try again."; + }; + + return ( +
+

Oops! Something went wrong

+

{getUserFriendlyErrorMessage(error)}

+ {process.env.NODE_ENV !== 'production' && ( +
+ Technical Details +
{error.message}
+
+ )} +
+ ); +} +``` + +## Common Issues and Resolutions + +### 1. Apollo Client + +1. **Issue**: Cache inconsistencies **Resolution**: Use `refetchQueries` option when mutating data or implement cache update functions. +2. **Issue**: Overfeching data **Resolution**: Utilize fragment colocation and implement proper query splitting. + +### 2. Urql + +1. **Issue**: Stale data after mutations **Resolution**: Use the `cache-and-network` fetch policy or implement manual cache updates. +2. **Issue**: SSR hydration mismatches **Resolution**: Ensure consistent query variables between server and client, or use the `ssrExchange`. + +### 3. React Query (all combinations) + +1. **Issue**: Stale data displayed briefly before refetch **Resolution**: Adjust `staleTime` and `cacheTime` options to fine-tune caching behavior. +2. **Issue**: Unnecessary refetches on component remount **Resolution**: Implement proper query keys and adjust `refetchOnMount` option. ### Use Cases for Each Method @@ -306,6 +569,6 @@ Here’s a comparison table to help choose the right method based on specific ne - **React Query + Axios**: Preferred when developers are already familiar with Axios and need robust HTTP capabilities. - **React Query + Fetch API**: Optimal for projects that require a minimalistic approach with no additional dependencies. -## Conclusion: +## Conclusion By understanding the distinct features and use cases of each method, developers can select the most appropriate GraphQL fetching technique for their React projects. This guide aims to equip developers with the knowledge to efficiently integrate GraphQL data fetching into their applications, regardless of scale or complexity. From 382e43bd51f830c1c3eeca7e20f96cb938f45f54 Mon Sep 17 00:00:00 2001 From: amit Date: Mon, 8 Jul 2024 10:51:53 +0530 Subject: [PATCH 5/5] style: lint --- graphql/graphql-react-client.md | 202 +++++++++++++++++--------------- 1 file changed, 110 insertions(+), 92 deletions(-) diff --git a/graphql/graphql-react-client.md b/graphql/graphql-react-client.md index 520a2c254..d3b34d41f 100644 --- a/graphql/graphql-react-client.md +++ b/graphql/graphql-react-client.md @@ -300,34 +300,33 @@ Utilizes the browser's Fetch API with React Query for a minimalistic approach. Here’s a comparison table to help choose the right method based on specific needs: +| Method | Bundle Size (minified + gzip)\* | Learning Curve | Caching Capabilities | Community Support | Additional Features | +| ----------------------------- | ------------------------------- | -------------- | --------------------------------------- | ----------------- | --------------------------------------- | +| Apollo Client | ~47.04 KB | Moderate | Extensive (InMemoryCache, customizable) | High | State management, optimistic UI updates | +| Urql | ~2.18 KB | Low | Moderate (Document caching) | Moderate | Extensible architecture | +| React Query + GraphQL Request | ~13 KB + ~185.8 KB | Low | Basic (Managed by React Query) | Growing | Minimal overhead | +| React Query + Axios | ~13 KB + ~13.2 KB | Low | Basic (Managed by React Query) | High | Familiar HTTP handling | +| React Query + Fetch API | ~13 KB + ~152.4 KB | Low | Basic (Managed by React Query) | Moderate | Browser-native, minimal setup | -| Method | Bundle Size (minified + gzip)* | Learning Curve | Caching Capabilities | Community Support | Additional Features | -| ----------------------------- | ----------------------------- | -------------- | ------------------------------------------- | ----------------- | --------------------------------------- | -| Apollo Client | ~47.04 KB | Moderate | Extensive (InMemoryCache, customizable) | High | State management, optimistic UI updates | -| Urql | ~2.18 KB | Low | Moderate (Document caching) | Moderate | Extensible architecture | -| React Query + GraphQL Request | ~13 KB + ~185.8 KB | Low | Basic (Managed by React Query) | Growing | Minimal overhead | -| React Query + Axios | ~13 KB + ~13.2 KB | Low | Basic (Managed by React Query) | High | Familiar HTTP handling | -| React Query + Fetch API | ~13 KB + ~152.4 KB | Low | Basic (Managed by React Query) | Moderate | Browser-native, minimal setup | - -(*) culled from *bundlephobia.com* +(*) culled from *bundlephobia.com\* ### Caching Capabilities 1. **Apollo Client**: - - Normalized caching (stores entities by ID) - - Automatic cache updates - - Manual cache manipulation - - Persistence and rehydration - - Optimistic updates + - Normalized caching (stores entities by ID) + - Automatic cache updates + - Manual cache manipulation + - Persistence and rehydration + - Optimistic updates 2. **Urql**: - - Document caching (stores full query responses) - - Customizable caching with exchangers - - Persistence support + - Document caching (stores full query responses) + - Customizable caching with exchangers + - Persistence support 3. **React Query** (applies to all React Query combinations): - - Time-based caching - - Stale-while-revalidate strategy - - Manual cache manipulation - - Persistence and rehydration + - Time-based caching + - Stale-while-revalidate strategy + - Manual cache manipulation + - Persistence and rehydration ## Error Handling @@ -338,7 +337,7 @@ Proper error handling is crucial for creating robust GraphQL applications. This Apollo Client provides detailed error information through the `error` property returned by the `useQuery` hook. It distinguishes between GraphQL errors and network errors. ```jsx -import { useQuery, gql } from "@apollo/client"; +import {useQuery, gql} from "@apollo/client" const LAUNCHES_QUERY = gql` { @@ -347,53 +346,57 @@ const LAUNCHES_QUERY = gql` mission_name } } -`; +` function SpaceXLaunches() { - const { data, loading, error } = useQuery(LAUNCHES_QUERY); + const {data, loading, error} = useQuery(LAUNCHES_QUERY) - if (loading) return "Loading..."; + if (loading) return "Loading..." if (error) { - return ; + return } // Render data... } -function ErrorDisplay({ error }) { +function ErrorDisplay({error}) { // Function to generate a user-friendly error message const getUserFriendlyErrorMessage = (error) => { if (error.networkError) { - return "Unable to reach the server. Please check your internet connection and try again."; + return "Unable to reach the server. Please check your internet connection and try again." } if (error.graphQLErrors.length > 0) { // You might want to customize this based on specific error codes or messages - return "There was an issue processing your request. Please try again later."; + return "There was an issue processing your request. Please try again later." } - return "An unexpected error occurred. Please try again."; - }; + return "An unexpected error occurred. Please try again." + } return (

Oops! Something went wrong

{getUserFriendlyErrorMessage(error)}

- {process.env.NODE_ENV !== 'production' && ( + {process.env.NODE_ENV !== "production" && (
Technical Details - {error.graphQLErrors.map(({ message, locations, path }, index) => ( -
-

GraphQL error: {message}

-

Location: {JSON.stringify(locations)}

-

Path: {JSON.stringify(path)}

-
- ))} + {error.graphQLErrors.map( + ({message, locations, path}, index) => ( +
+

GraphQL error: {message}

+

Location: {JSON.stringify(locations)}

+

Path: {JSON.stringify(path)}

+
+ ), + )} {error.networkError && ( -

Network error: {error.networkError.message}

+

+ Network error: {error.networkError.message} +

)}
)}
- ); + ) } ``` @@ -408,7 +411,7 @@ This example demonstrates how to: Urql provides error information through the `error` property in the result object. ```tsx -import { useQuery } from "urql"; +import {useQuery} from "urql" const LAUNCHES_QUERY = ` { @@ -417,57 +420,67 @@ const LAUNCHES_QUERY = ` mission_name } } -`; +` function SpaceXLaunches() { - const [result] = useQuery({ query: LAUNCHES_QUERY }); - const { data, fetching, error } = result; + const [result] = useQuery({query: LAUNCHES_QUERY}) + const {data, fetching, error} = result - if (fetching) return "Loading..."; + if (fetching) return "Loading..." if (error) { - return ; + return } // Render data... } -function ErrorDisplay({ error }) { +function ErrorDisplay({error}) { const getUserFriendlyErrorMessage = (error) => { if (error.networkError) { - return "Unable to reach the server. Please check your internet connection and try again."; + return "Unable to reach the server. Please check your internet connection and try again." } if (error.graphQLErrors.length > 0) { // Customize based on specific error types if needed - return "There was an issue processing your request. Please try again later."; + return "There was an issue processing your request. Please try again later." } - return "An unexpected error occurred. Please try again."; - }; + return "An unexpected error occurred. Please try again." + } return (

Oops! Something went wrong

{getUserFriendlyErrorMessage(error)}

- {process.env.NODE_ENV !== 'production' && ( + {process.env.NODE_ENV !== "production" && (
Technical Details - {error.graphQLErrors.map((graphQLError, index) => ( -
-

GraphQL error: {graphQLError.message}

- {graphQLError.locations && ( -

Location: {JSON.stringify(graphQLError.locations)}

- )} - {graphQLError.path && ( -

Path: {JSON.stringify(graphQLError.path)}

- )} -
- ))} + {error.graphQLErrors.map( + (graphQLError, index) => ( +
+

GraphQL error: {graphQLError.message}

+ {graphQLError.locations && ( +

+ Location:{" "} + {JSON.stringify(graphQLError.locations)} +

+ )} + {graphQLError.path && ( +

+ Path:{" "} + {JSON.stringify(graphQLError.path)} +

+ )} +
+ ), + )} {error.networkError && ( -

Network error: {error.networkError.message}

+

+ Network error: {error.networkError.message} +

)}
)}
- ); + ) } ``` @@ -478,10 +491,10 @@ React Query provides error information through the `error` property returned by When using React Query with GraphQL Request, you need to handle errors from both libraries. This approach requires more manual error handling but offers fine-grained control. ```tsx -import { useQuery } from "react-query"; -import { request, gql } from "graphql-request"; +import {useQuery} from "react-query" +import {request, gql} from "graphql-request" -const endpoint = "https://api.spacex.land/graphql/"; +const endpoint = "https://api.spacex.land/graphql/" const LAUNCHES_QUERY = gql` { launchesPast(limit: 10) { @@ -489,58 +502,63 @@ const LAUNCHES_QUERY = gql` mission_name } } -`; +` function SpaceXLaunches() { - const { data, isLoading, error } = useQuery("launches", async () => { - try { - return await request(endpoint, LAUNCHES_QUERY); - } catch (error) { - // GraphQL Request wraps GraphQL errors in a ClientError - if (error.response) { - throw new Error(JSON.stringify(error.response.errors)); - } else { - // Network error - throw new Error(`Network error: ${error.message}`); + const {data, isLoading, error} = useQuery( + "launches", + async () => { + try { + return await request(endpoint, LAUNCHES_QUERY) + } catch (error) { + // GraphQL Request wraps GraphQL errors in a ClientError + if (error.response) { + throw new Error( + JSON.stringify(error.response.errors), + ) + } else { + // Network error + throw new Error(`Network error: ${error.message}`) + } } - } - }); + }, + ) - if (isLoading) return "Loading..."; + if (isLoading) return "Loading..." if (error) { - return ; + return } // Render data... } -function ErrorDisplay({ error }) { +function ErrorDisplay({error}) { const getUserFriendlyErrorMessage = (error) => { try { - const parsedError = JSON.parse(error.message); + const parsedError = JSON.parse(error.message) if (Array.isArray(parsedError)) { // GraphQL errors - return "There was an issue processing your request. Please try again later."; + return "There was an issue processing your request. Please try again later." } } catch { // Network error or other non-GraphQL error - return "Unable to reach the server. Please check your internet connection and try again."; + return "Unable to reach the server. Please check your internet connection and try again." } - return "An unexpected error occurred. Please try again."; - }; + return "An unexpected error occurred. Please try again." + } return (

Oops! Something went wrong

{getUserFriendlyErrorMessage(error)}

- {process.env.NODE_ENV !== 'production' && ( + {process.env.NODE_ENV !== "production" && (
Technical Details
{error.message}
)}
- ); + ) } ```