Recoil: Getting recoil state inside fetch-query function

Created on 29 Sep 2020  路  6Comments  路  Source: facebookexperimental/Recoil

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,
  });
}

Most helpful comment

@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.

All 6 comments

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

adrianbw picture adrianbw  路  3Comments

Sawtaytoes picture Sawtaytoes  路  4Comments

robsoncezario picture robsoncezario  路  3Comments

karevn picture karevn  路  3Comments

eLeontev picture eLeontev  路  3Comments