T
TanStack4y ago
xenial-black

How to approach the need for instant state?

I wanted to get people's opinions on how to manage the below situation. At the moment we use redux to fetch a global user object and use some data in our headers. Obviously, a straight replacement of redux to RQ won't work in this instance as the data is undefined initially. I can manage most uses of undefined in the UI with redirects etc but this is bit different. current implementation:
export const getHeaders = (reduxState) => {
let headers = {};
if (reduxState.token !== "") {
headers = {
...headers,
"Authorization": `Token ${reduxState.token}`
};
}
if (reduxState.language !== "") {
headers = {
...headers,
"Accept-Language": `${reduxState.language}`
};
}

return headers;
};

export const useHeaders = () => {
const reduxState = useSelector((state) => state);
return getHeaders(reduxState, globalUserData);
};
export const getHeaders = (reduxState) => {
let headers = {};
if (reduxState.token !== "") {
headers = {
...headers,
"Authorization": `Token ${reduxState.token}`
};
}
if (reduxState.language !== "") {
headers = {
...headers,
"Accept-Language": `${reduxState.language}`
};
}

return headers;
};

export const useHeaders = () => {
const reduxState = useSelector((state) => state);
return getHeaders(reduxState, globalUserData);
};
The headers are used in various get requests, as an example:
export const useFetchUser = () => {
const { store } = useContext(ReactReduxContext);
const reduxState = store.getState();
return useQuery([user.fetchUser],
async () => {
const { data } = await axios({
url: UserUrl,
headers: { ...getHeaders(reduxState) },
method: "get"
});
return data;
}
);
};
export const useFetchUser = () => {
const { store } = useContext(ReactReduxContext);
const reduxState = store.getState();
return useQuery([user.fetchUser],
async () => {
const { data } = await axios({
url: UserUrl,
headers: { ...getHeaders(reduxState) },
method: "get"
});
return data;
}
);
};
4 Replies
xenial-black
xenial-blackOP4y ago
My naive implementation of switching to RQ:
export const getHeaders = (globalUserData) => {
let headers = {};
if (globalUserData.token !== "") {
headers = {
...headers,
"Authorization": `Token ${globalUserData.token}`
};
}
if (globalUserData.language !== "") {
headers = {
...headers,
"Accept-Language": `${globalUserData.language}`
};
}

return headers;
};

export const useHeaders = () => {
const { data: globalUserData } = useFetchUser();
return getHeaders(globalUserData);
};
export const getHeaders = (globalUserData) => {
let headers = {};
if (globalUserData.token !== "") {
headers = {
...headers,
"Authorization": `Token ${globalUserData.token}`
};
}
if (globalUserData.language !== "") {
headers = {
...headers,
"Accept-Language": `${globalUserData.language}`
};
}

return headers;
};

export const useHeaders = () => {
const { data: globalUserData } = useFetchUser();
return getHeaders(globalUserData);
};
How are other people managing this?
fair-rose
fair-rose4y ago
not sure what the question is. of course data is undefined at first because it comes from a remote source ...
xenial-black
xenial-blackOP4y ago
Ok, so if we move away from the fact that data is undefined at first, which I understand, let’s take another example which ties in well with my original question. I have 1 endpoint /users that fetches the user. The data returned from /users (token, email etc) is used in various places throughout the app. I can create a customhook to fetch the data which can be re-used thoughout the app when we need some data from /users. However, this means we re-fetch the data every time the hook is used, which means the data is returned as undefined initially. Is a solution to fetch the user once, and then spread the data via useContext, or do I need to tweak some config and use the cache to its full advantage?
export const useFetchUser = () => {
return useQuery([user.fetchUser],
async () => {
const { data } = await axios({
url: userUrl,
method: "get"
});
return data;
}
);
};
export const useFetchUser = () => {
return useQuery([user.fetchUser],
async () => {
const { data } = await axios({
url: userUrl,
method: "get"
});
return data;
}
);
};
fair-rose
fair-rose4y ago
you don't refetch every time the hook is used if you set staleTime. please read: https://tkdodo.eu/blog/react-query-as-a-state-manager
React Query as a State Manager
Everything you need to know to make React Query your single source of truth state manager for your async state

Did you find this page helpful?