Missing queryFn error when using useQuery
Asked Answered
C

7

14

As the title suggests, I am new to using useQuery and the associated libraries, I am trying to use it to fetch data and then populates a list of fields that I have created However when I run it I get this error after it makes two requests

Missing queryFn index.js:1
    e index.js:1
    onError query.js:356
    reject retryer.js:67
    run retryer.js:132
    (Async: promise callback)
    run retryer.js:116
    Retryer retryer.js:156
    fetch query.js:330
    executeFetch queryObserver.js:199
    onSubscribe queryObserver.js:40
    subscribe subscribable.js:16
    useBaseQuery useBaseQuery.js:60
    React 5
    unstable_runWithPriority scheduler.development.js:468
    React 3
    workLoop scheduler.development.js:417
    flushWork scheduler.development.js:390
    performWorkUntilDeadline scheduler.development.js:157
    (Async: EventHandlerNonNull)
    js scheduler.development.js:180
    js scheduler.development.js:645
    Webpack 21

As far as I can tell I have passed in a query function so I am very confused why this error is showing I can see the server is receiving the requests and seemingly sends it, I have tested elsewhere and server does send it so it has to be with my code right?

const URL = 'http://localhost:3500/monster';
const fetchMonster = async (id) => {
    console.log(id);
    let res = await fetch(`${URL}/${id}`);
    if (!res.ok) {
        throw new Error('Network response was not ok');
    }
    return res.json;
};
const queryClient = new QueryClient({
    defaultOptions: {
        queries: {
            retry: process.env.NODE_ENV === 'production',
            refetchOnWindowFocus: false,
        },
    },
})

function EditMonster(props) {
    let { slug } = useParams();
    return (
        <QueryClientProvider client={queryClient}>
            <Query
                slug={slug} />
        </QueryClientProvider>
    )
}

function Query(props) {
    const { isLoading, error, data } = useQuery('monster', fetchMonster(props.slug))

    if (isLoading) return 'Loading...';
    if (error) return 'An error has occured: ' + error.message;

    return (
        <AttributeFields name='Edit Monster' method='PATCH' monster={data} />
    )
}
Capias answered 11/12, 2021 at 23:33 Comment(0)
B
34

useQuery('monster', fetchMonster(props.slug))

this code does not pass a function to useQuery - it immediately invokes the function. What you want is:

useQuery('monster', () => fetchMonster(props.slug))

As a side note, dependencies to the query function should go to the query key:

useQuery(['monster', props.slug], () => fetchMonster(props.slug))

Butterfat answered 12/12, 2021 at 6:25 Comment(1)
lol as I read this comment I thought "hey that looks like TkDodo's recommended query key structure" and then I looked at the user who answered this question and it's the same. Great advice here: tkdodo.eu/blog/effective-react-query-keys#structurePolito
B
19

For those searching for answers from 2022, you simply need to pass your first parameter to useQuery as an array like so:

useQuery(['monster'], () => fetchMonster(props.slug))

and your request works.

Bedplate answered 10/8, 2022 at 8:57 Comment(1)
Yep, that's the one.Hyperbolize
B
1

The thing we are missing here is that you might have set the value for 'monster' query somewhere in your code. If the query value is set before it's been fetched we get this issue.

Bread answered 23/8, 2022 at 7:26 Comment(1)
Any idea how to fix this issue? I assumed that the cache will just return the value that was previously fetchedYearlong
T
0

The problem is that it need a function but passing the function you are calling the function.

It should be like eg:

const { isLoading, error, data } = useQuery('monster', () => fetchMonster(props.slug))

just rap fetchMonster function in side in to a arrow function that's all.

Tangled answered 24/11, 2022 at 10:9 Comment(0)
N
0

two reasons may cause this issue, the first one is not using the async function and the second is not passing query function dependency with the query key. finally, the query function should be typed like this

const { data, isFetching, refetch } = useQuery(
  // dependency is passed here
  ["user data", session?.user._id],

  // async fucntion
  async () => await getUserData(session?.user._id)
);
Nmr answered 29/1, 2023 at 22:0 Comment(0)
K
0

On my end, I wanted to pass id as param in useQuery. Here it is my implementation.

=> hooks.js

const useListingById = (id) => {
    return useQuery(["listings", id], () => listingServices.getListingById(id));
};
=> [id].js

const { data, error, isFetching } = useListingById(id)
Kendyl answered 22/10, 2023 at 15:34 Comment(0)
P
0
const fetchMonster = async ({queryKey}) => {
    const id = queryKey[1];
    console.log(id);
    let res = await fetch(`${URL}/${id}`);
    if (!res.ok) {
        throw new Error('Network response was not ok');
    }
    return res.json;
};    

const { isLoading, error, data } = useQuery(['monster',props.slug], fetchMonster);




   
Pe answered 1/12, 2023 at 7:50 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.