Using react-query to store global state? #2852
-
I'm switching our data access to lean on react-query. I'm also generally moving towards functional components and hooks. Thus, it seems like using mobx for our global state is potentially not the right answer anymore. There are a few libraries designed for managing global state in an efficient way where consumers transparently "subscribe" to specific updates through hooks. I thought, "but react-query kinda does this already . . . I wonder if I could make a hook and use react-query for global state." So, I did. But, I was so preoccupied with whether or not I could, I didn't stop to think if I should. What do you folks think about something like this (this is just a proof of concept)? Is this a terrible idea? Am I missing something I should be considering? https://codesandbox.io/s/useglobalstate-with-react-query-k3zkb import { useQuery, useQueryClient } from "react-query";
interface SetGlobalState<T> {
(newState: T): void;
}
const GLOBAL_STATE_KEY_PREFIX = "globalState";
export function useGlobalState<T = undefined>(key: string): [T, SetGlobalState<T>];
export function useGlobalState<T>(key: string, initialState: T): [T, SetGlobalState<T>];
export function useGlobalState<T>(key: string, initialState?: T): [T | undefined, SetGlobalState<T>] {
const queryClient = useQueryClient();
const stateKey = [GLOBAL_STATE_KEY_PREFIX, key];
const { data } = useQuery(stateKey, () => initialState, {
initialData: initialState,
staleTime: Infinity
});
const setData = (newState: T) => {
queryClient.setQueryData(stateKey, newState);
};
return [data, setData];
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
When you're talking about global state, you do mean client state, because react-query already is a global server state manager. Call useQuery with the same key twice and you'll get the data. while you certainly can do it, I don't think you should, for the following reasons:
That being said, your solution comes close to a nicely working solution, and you've also added types, but there are no partial updates, no bailing out of state updates etc. zustand can do all of that really well, for <1kb of bundle sizes. I see no reason to not use zustand instead :) |
Beta Was this translation helpful? Give feedback.
When you're talking about global state, you do mean client state, because react-query already is a global server state manager. Call useQuery with the same key twice and you'll get the data.
while you certainly can do it, I don't think you should, for the following reasons:
() => 5
from thequeryFn
, it's still being converted to aPromise
, so you'll get one render cycle where your state isloading
anddata
isundefined
. In your example, you are working around this by settinginitialData
andstaleTime: Infinite
, so thequeryFn
is actually never called.