question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proposal to add a new hook useSubscribeToMore

See original GitHub issue

I’ve opened a issue with a question about an alternative alternative to query.subscribeToMore (#122). But if it’s not possible i thinks this proposal will help.

I’m using this custom hooks that I made. But I think this can be a part of this awesome library. 😜. What do you think @trojanowski?

useSubscribeToMore.js

import { useEffect, useState } from 'react';
import { useSubscription } from 'react-apollo-hooks';

export function useSubscribeToMore(query, { document, updateQuery }) {
  const [data, setData] = useState(query.data);

  const handleSubscriptionData = (options) => {
    setData((prevData) => {
      const nextData = updateQuery(prevData, options);
      if (nextData === undefined) {
        return prevData;
      }
      return nextData;
    });
  };

  const subscription = useSubscription(document, {
    onSubscriptionData: handleSubscriptionData,
  });

  useEffect(() => {
    setData(query.data);
  }, [query.data]);

  return {
    ...query,
    data,
    subscription,
  };
}

Usage eg: messagesExample.js

import React from 'react';
import gql from 'graphql-tag';
import { useQuery } from 'react-apollo-hooks';
import { useSubscribeToMore } from './useSubscribeToMore';

const MESSAGE_FRAGMENT = gql`
  fragment Message on Message {
    id
    body
    createdAt
  }
`; 

const MESSAGE_QUERY = gql`
  query {
    messages {
      ...Message
    }
  }
  ${MESSAGE_FRAGMENT}
`;

const MESSAGE_SUBSCRIPTION =  gql`
  subscription {
    messageAdded {
      ...Message
    }
  }
  ${MESSAGE_FRAGMENT}
`;

export function Messages() {
  const messageQuery = useQuery(MESSAGE_QUERY);
  const { data, loading, error } = useSubscribeToMore(messageQuery, {
      document: MESSAGE_SUBSCRIPTION,
      updateQuery: (data, { subscriptionData }) => {
        if (!subscriptionData.data) {
          return void 0;
        }

        return { 
          ...prev,
          messages: [ ...prev.messages, subscriptionData.data.messageAdded],
        };
      }
  });

  if (loading) {
    return (<p>Loading...</p>);
  }

  if (error) {
    return (<p>Something is wrong, try again...</p>);
  }

  return (
    <div>
      {data.messages.map(({ id, body, createdAt }) => (
        <div key={id}>
          <p>{body}</p>
          <time>{createdAt}</time>
          <hr />
        </div>
      ))}
    </div>
  );
}

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
trojanowskicommented, Apr 3, 2019

@RodolfoSilva there is a problem with this solution - it doesn’t save the updated data to the Apollo cache, so you’d see outdated data if the component unmounted and mounted again. useSubscription hook has builtin support for updating the cache with subscription data with the onSubscriptionData option. It works similar to the update option for mutation. messagesExample.js can be rewritten that way with it:

const { data, error, loading } = useSubscription(MESSAGE_SUBSCRIPTION, {
  onSubscriptionData: ({ client, subscriptionData }) => {
    // Client is an instance of Apollo client.
    // It has cache proxy method used in the `update` option in mutations.
    // Please look at: https://www.apollographql.com/docs/react/essentials/mutations#update
    const cachedMessages = client.readQuery({
      query: MESSAGE_QUERY
    });
    cachedMessages.messages.push(subscriptionData.messageAdded);
    client.writeQuery({
      query: MESSAGE_QUERY,
      data: cachedMessages,
    })
  }
});
1reaction
fbarthocommented, Aug 20, 2020

@IsaacTrevino this library is in maintenance mode. It existed to add hooks support to Apollo, and is no longer necessary when you’re using modern Apollo!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Subscriptions - Apollo GraphQL Docs
You use Apollo Client's useSubscription Hook to execute a subscription from React. Like useQuery , useSubscription returns an object from Apollo Client that ......
Read more >
All About React's Proposed New use() Hook
A feature proposal from the React core team is causing some buzz in the React ecosystem: the new use() hook adds first class...
Read more >
Cannot read property 'subscribeToMore' of undefined in Apollo
I tried with const {data} = subscriptionData; return Object.assign({}, prev, data); and I'm still getting the error. It seems that ...
Read more >
React may be getting a new hook — useEvent | by Kolby Sisk
On May 4th the React team published an RFC proposing a new React hook ... In short the useEvent hook will make developer's...
Read more >
A Proposal for an Alternative Design for Hooks - paulgray.net
I enjoy using React every day, and it's all credit to your hard work. ... At the core of the API, there would...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found