Im using react with relay.. + Recoil for state management
In relay fetch query i check for cookies and if cookie with user_id change, im regenerating environment and i wanna get current state from recoil where global user id is stored (for needs to compare it with cookie )
But im not able to find way to get that out of hook.. i need to check that cookies and get recoil state in all fetch respons... that is why im trying to put it in global fetch query..
What is correct way of accessing recoil state out of useRecoilState ... out of using hook.. ?
function fetchQuery(
operation,
variables,
cacheConfig
) {
const queryID = operation.text;
const isMutation = operation.operationKind === "mutation";
const isQuery = operation.operationKind === "query";
const forceFetch = cacheConfig && cacheConfig.force;
// Try to get data from cache on queries
const fromCache = cache.get(queryID, variables);
const [userStore, setUserStore] = useRecoilState(projectselector);
function checkCookies() {
const cookie_user_id = getUserIdFromCookie();
if (cookie_user_id) {
const value = parseInt(cookie_user_id);
if (value !== 0 && userStore.user_id !== value) {
setUserStore({ user_id: value });
return true;
}
}
return false;
}
if (isQuery && fromCache !== null && !forceFetch) {
return fromCache;
}
// Otherwise, fetch data from server
return fetch(BASE_GRAPHQL_URL, {
credentials: "include",
// mode: "cors",
method: "POST",
headers: {
Accept: "application/json",
// "Access-Control-Allow-Origin": "http://localhost:3000/",
"Content-Type": "application/json",
},
body: JSON.stringify({
query: operation.text,
variables,
operationName: operation.name,
}),
})
.then((response) => {
if (checkCookies()) {
// todo
}
return response.json();
})
.then((json) => {
// Update cache on queries
if (isQuery && json) {
cache.set(queryID, variables, json);
}
// Clear cache on mutations
if (isMutation) {
cache.clear();
}
return json;
});
}
export function createEnvironment() {
const network = Network.create(fetchQuery);
const store = new Store(new RecordSource());
return new Environment({
network,
store,
});
}
Relevant issues and possible solutions:
https://github.com/facebookexperimental/Recoil/issues/410
https://github.com/facebookexperimental/Recoil/issues/546
https://github.com/facebookexperimental/Recoil/issues/562
@drarmstr This question comes up a lot, perhaps there should be a page in the docs about sync'ing with state that lives outside of Recoil?
Hi @BenjaBobs thx for pointing this out..
@drarmstr This question comes up a lot, perhaps there should be a page in the docs about sync'ing with state that lives outside of Recoil?
@BenjaBobs - There is this page in the docs discussing some state synchronization approaches. Though, I'm not a big fan of it. I'm planning to provide a new guide in the coming weeks based on the experimental API.
I currently decided to use global variable to hold this user_id because this sync is bit complicated to do just for one state variable... Mainly if i imagine that somebody else looks in code.... will need to read and understand it... And this make sync approach too over-complicated... It is OK with subscriptions.. but with single variable bit overkill..
BTW i find nice connection between zustand and recoil.. So for now im using zustand for any out of root storage and interaction... and connect it to recoil based on subscriptions and sync....
Updated documentation for syncing Recoil state with external storage in #680
Most helpful comment
@BenjaBobs - There is this page in the docs discussing some state synchronization approaches. Though, I'm not a big fan of it. I'm planning to provide a new guide in the coming weeks based on the experimental API.