jaydenseric / graphql-react

A GraphQL client for React using modern context and hooks APIs that is lightweight (< 4 kB) but powerful; the first Relay and Apollo alternative with server side rendering.
https://npm.im/graphql-react
MIT License
718 stars 22 forks source link

Support polling? #16

Closed jthegedus closed 5 years ago

jthegedus commented 5 years ago

A more simple method to support somewhat real time data than subscriptions would be a polling mechanism. Is this something you would consider adding?

jaydenseric commented 5 years ago

It's very easy to make your own polling query component, something like:

import { Component } from 'react'
import { Query } from 'graphql-react'

class Polling extends Component {
  componentDidMount() {
    this.intervalId = setInterval(this.props.callback, this.props.interval)
  }

  componentWillUnmount() {
    clearInterval(this.intervalId)
  }

  render() {
    return this.props.children
  }
}

const PollingQuery = ({ interval, children, ...queryProps }) => (
  <Query {...queryProps}>
    {queryRenderArgs => (
      <Polling interval={interval} callback={queryRenderArgs.load}>
        {children(queryRenderArgs)}
      </Polling>
    )}
  </Query>
)

I have not tried it out personally, but it should be doable.

See here for past discussion on the technique:

https://gist.github.com/dburles/c8a6921fcfd4c0f40a9f805d0c9fd437#gistcomment-2590729

jthegedus commented 5 years ago

Thanks for this :100:

Update: here is a hooks example using useInterval for anyone looking:

import React from 'react';
import useInterval from '@use-it/interval';
import { useGraphQL } from 'graphql-react';

function PollingQuery(props) {
  const { load, loading, cacheValue={} } = useGraphQL({
    fetchOptionsOverride(options) {
      options.url = 'https://graphql-pokemon.now.sh'
    },
    operation: {
      query: `{ pokemon(name: "${name}") { image } }`
    }
  })

  useInterval(() => {
      load();
  }, props.interval);

  return cacheValue.data ? (
    <img src={cacheValue.data.pokemon.image} alt={name} />
  ) : loading ? (
    'Loading…'
  ) : (
    'Error!'
  )
}

export default PollingQuery