Hooks are not supported inside an async component error in nextjs project using useQuery

27 views Asked by At

I've been having trouble with how I'm supposed to fetch the data using an API call. I'm using useQuery and I've looked around for how I'm supposed to implement it and I'm just getting errors with it and async keywords that may or may not be needed in the file. I'm just confused with use client and what should and shouldn't be in that kind of file.

Here's how I have useQuery set up


"use client"

import { useQuery } from "@tanstack/react-query";
import fetchData from "../app/fetchData.jsx";  

export default function Temps(){
  
    const{  data, error, isError } = useQuery({
         queryKey: ["wdata"], 
         queryFn:  () =>  fetchData(),
        
    });   
      
      if (isError) <span>Error: {error.message}</span>
      if(data)
      return(
        <div>
        <p> {data.toString()}</p>
        </div>
      )
  
    }

Here's where I have fetchData


"use client"

import { usePathname } from "next/navigation";


async function getData(){
  const options = {
    method:"GET",
    headers: {
      accept: "application/json",
    },
  };

  
    const pathName = usePathname();

    const { searchParams } = pathName;
    const lat = searchParams.get('lat');
    const lon = searchParams.get('lon');


    const response = await fetch(
        `http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${process.env.API_KEY}&units=imperial`,
        options)
          .then ((response) => response.json())
          .catch((err) => console.error(err));

    return response;

}

export default async function fetchData(){
  

const data = await getData();
return data;

}

I'm thinking there might be something in the above code that's causing the error. Maybe the usePathname and searchParams but I'm not exactly sure how I should solve it.

also here's the home page where I use useQueryClient

import WeatherApp from './WeatherApp';
import { QueryClient } from '@tanstack/react-query';
import fetchData from './fetchData';
import Temps from '@/components/Temps';

export default  async function Home() {
  const queryClient = new QueryClient()
await queryClient.prefetchQuery({
  queryKey: ["wdata"],
  queryFn: () =>  fetchData(),
})
  
  return (
    <div>
    <WeatherApp />
    <Temps />
    </div>
  );
}

1

There are 1 answers

3
Drew Reese On

You can't call a React hook in a nested callback, i.e. calling usePathname in getData is not valid.

You can call usePathname in the Temps component and pass the lat, and lon values to the query function.

Basic Example:

"use client"

import { useQuery } from "@tanstack/react-query";
import { usePathname } from "next/navigation";
import fetchData from "../app/fetchData.jsx";  

export default function Temps() {
  const { searchParams } = usePathname();

  const lat = searchParams.get('lat');
  const lon = searchParams.get('lon');

  const { data, error, isError } = useQuery({
    queryKey: ["wdata", lat, lon], 
    queryFn: () =>  fetchData({ lat, lon }),
  });   
      
  if (isError) <span>Error: {error.message}</span>;

  if (data)
    return (
      <div>
        <p> {data.toString()}</p>
      </div>
    );
  }
}
"use client"

import { usePathname } from "next/navigation";

async function getData({ lat, lon }) {
  const options = {
    method:"GET",
    headers: {
      accept: "application/json",
    },
  };

  try {
    const response = await fetch(
      `http://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${process.env.API_KEY}&units=imperial`,
       options
    )
    const data = await response.json();
    return data;
  } catch(err) {
    console.error(err);
    throw err; // re-throw for query
  };
}

export default async function fetchData({ lat, lon }) {
  return getData({ lat, lon });
}