5

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 Answer 1

13

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I get that but what if I have a getTemplates call at the parent level. And I want all my children to have access to the data that this getTemplate call makes. Would I want to store the data property from the query call in a global property like a provider instead of storing the hook itself? I see what you're saying.
No, you would just call useQuery in the child again, and react-query will give you the data from the cache.
I see. Because it's the same query key it caches the query based off the query key and you can adjust the cache properties. This helps a lot thank you!
Yes, that’s exactly the idea. And custom hooks help in abstracting that away, which makes it a breeze to work with :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.