react-query useQuery inside a provider with with dynamic parameters

Viewed 8321

I'm using react query because it's super powerful but I'm struggling trying to share my data across many components inside a provider. I'm wondering if this is the right approach.

PostsContext.js

import React, {useState} from 'react';
import { useTemplate } from '../hooks';

export const PostsContext = React.createContext({});

export const PostsProvider = ({ children }) => {
    const fetchTemplate = useTemplate(templateId);
   
    const context = {
        fetchTemplate,
    };

    return <PostsContext.Provider value={context}>{children}</PostsContext.Provider>;
};

useTemplate.js

import React from 'react';
import { useQuery } from 'react-query'
import { getTemplateApi } from "../api";

export default function useTemplate(templateId) {
    return useQuery(["templateId", templateId], () => getTemplateApi(templateId), {
        initialData: [],
        enabled:false,
    });
}

and then my component that uses the context

function Posts () {
    const { fetchTemplate } = useContext(PostsContext);

    console.log(fetchTemplate.isLoading)

    fetchTemplate.refetch() <---- how can I refetch with a different templateId?

    return {...}

}

I'm looking for a way to dynamically call my hook with a different templateId but with the hook inside the provider so I can use it all over my app. Is this the right approach? I have deeply nested components that I don't want to prop drill.

1 Answers

You don’t need an extra way to distribute your data, like react context. Just call useQuery with the same key wherever you need to, and react query will do the rest. It is best to abstract that away in a custom hook.

refetch should only be used if you want to refetch with the exact same parameters. For changing parameters, it’s best to. make them part of your query key, because react query will refetch whenever the query key changes.

So in your example, you only need to call useTemplate with a different templateId. templateId itself is local state (which template has been selected by the user or so), and how you make that globally available is up to you.

Related