How to automatically update a reactiveVar after the query execution in Apollo?

Viewed 177

I fetch from the server a Posts array. Apollo stores it in the cache but I would like to store it in the reactive variable as well. I want to have the reactive variable with this data to be able to quickly manipulate the data on the client only, without affecting the server and only when some conditions are met I'll update the server. Also, the server data supports pagination so need to be able to update the reactive variable during the lifecycle when Apollo fetches a new data bucket from the server.

Basically, I tried to trigger the query that fetches data from the server in my component to get the initial data and then I updated the reactiveVar but in this case, I received double re-render, first for the Query, second for the reactive var update, so I'd like to avoid that because it's a bit counterproductive. Also, on every apollo mutation, I manually update the reactiveVar.

So I'm wondering what is the best way to handle this feature?

In the case of a combination Mobx + a simple fetch (axios) such things are extremely simple but in the case of Apollo, I'm confused a bit.

here is the code example:

The reactive var

const channelObject = {
  id: 'id_0',
  messages: []
};

export const channelReactiveVar = makeVar(channelObject);

The cache

export const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        channelClient: {
          read: () => channelReactiveVar()
        }
     }...;

Here is the local client query

    export const GET_CHANNEL_QUERY_CLIENT = gql`
      query channelClient {
        channelClient @client
      }
    `;

In my component: (simplified code)

function Component(props: any) {

  // fetch the inital posts data from the server 
  const {
    data: postData,
  } = useQuery(GET_POSTS_QUERY, {
    variables: {
      communityId: photoContent.communityId,
      parentId: null,
      first: 5,
      after: '',
    },
    notifyOnNetworkStatusChange: true,
  });

  // receive the local state from reactve var
  const { data } = useQuery(GET_CHANNEL_QUERY_CLIENT);

  // update the local reactive var after the data came from the server
  React.useEffect(() => {
    if (postData) {
      channelReactiveVar(postData)
    }
    
  }, [postData]);

  const [createComment, { loading, error }] = useMutation(
    CREATE_COMMENT,
    {
      // updating the reactive var after the server mutation finishes
      onCompleted: () => {

      channelReactiveVar({
        ...channelReactiveVar,
        // the array that contains a new item. I've ommited here the payload generation
        messages: newMessages 
      });
     }
    }
  );
  ...

Thank you for any information or help!

1 Answers

You can use skip option in useQuery

Related