React re-render causing Apollo useQuery to be called twice
Asked Answered
O

0

8

I have a simple React component that uses Apollo's useQuery to fetch data. The problem is, because the component is being rendered twice, it is calling useQuery twice, which is then calling the Apollo resolver twice, which is then calling the associated function that fetches and returns the data twice, which we can all agree is not great.

How do I stop the data fetching function from being called multiple times?


Project Details

A simple console.log statement in the data fetching function is showing that it is getting called twice.

import { useEffect } from "react";
import { useQuery, useMutation, gql } from "@apollo/client";
import { Wrapper, Title } from "./App.styles";

const GET_SIGNALS = gql`
  query {
    charts {
      symbol
      price
    }
  }
`;

const App = () => {
  const { loading, error, data } = useQuery(GET_SIGNALS);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error...</p>;

  console.log(data);

  return (
    <Wrapper>
      <Title>Trend List</Title>
    </Wrapper>
  );
};

export default App;

Here's the Apollo server:

import { ApolloServer, gql } from "apollo-server-micro";
import { getCharts } from "../../src/getCharts";

const typeDefs = gql`
  type Chart {
    symbol: String
    price: [String]
  }

  type Query {
    charts: [Chart]
  }
`;

const resolvers = {
  Query: {
    charts: () => getCharts(),
  },
};

const server = new ApolloServer({ typeDefs, resolvers });

const handler = server.createHandler({ path: "/api/graphql-api" });

export const config = {
  api: {
    bodyParser: false,
  },
};

export default handler;

The getCharts() functions just returns an object that fits the type definitions.

export const getCharts = async () => {
  console.log("1. Starting getCharts");
  return [{ symbol: "BTCUSDT", price: ["1", "2", "3"] }];
};

So the output is:

1. Starting getCharts
1. Starting getCharts
Oui answered 12/4, 2021 at 14:34 Comment(1)
I don't see the component being rendered twice? A working fiddle would be good (even without any backend, we could see that two requests are being made). Anyway, two components have no way to know that they're doing the same query, or that it will return the same result. You'll need some shared or global state.Exum

© 2022 - 2024 — McMap. All rights reserved.