reactjsreact-hooksapolloreact-apolloreact-apollo-hooks

Invalid hook call. Hooks can only be called inside of the body of a function component when i call useQuery in useEffect


I am using apollo-graphql in my react project and i am getting error of

Invalid hook call. Hooks can only be called inside of the body of a function component

Here is my code for this

import React, { useEffect, useState, useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";

// **************** COMPONENTS ****************
import { GET_MORTGAGE_JOURNEY } from "../../../../Graphql/Journeys/query";

export default function index() {
  const insuranceId = useSelector((state) => state.mortgage.insuranceId);

  // Panels Heading to show on all panels

  useEffect(() => {
    if (insuranceId) {
      getMortgageData(insuranceId);
    }
  }, [insuranceId]);

  function getMortgageData(insuranceId) {
    const { loading, error, data } = useQuery(GET_MORTGAGE_JOURNEY, {
      variables: { id: insuranceId },
    });
    console.log(data);
  }

  return <section className="mortage-journey"></section>;
}

Once i run this i get the error, I know that useQuery itself is a hook and i cant call it from inside useEffect, but then what should be the workaround for this as i need insuranceId from my redux state first and send it to the query.

Thanks !


Solution

  • You are breaking the rule of hooks when you call it from any place other than the top level of a React component.

    useEffect takes a callback function, and you are calling your hook from that. It is a problem.

    I found this skip option in useQuery which helps you call useQuery conditionally.

        const { loading, error, data } = 
        useQuery(GET_MORTGAGE_JOURNEY, {
          variables: { id: insuranceId },
          skip : (!insuranceId)
        });
    
    

    Any time insuranceId changes your callback runs, so it is run after mount once and then on subsequent changes.