samdenty / gqless

a GraphQL client without queries
https://gqless.com
3.66k stars 54 forks source link

Possible usage of hooks with `useQuery` / `useSubscription` #192

Open samdenty opened 3 years ago

samdenty commented 3 years ago

We could enable usage of the hooks logic, without importing useQuery or useSubscription.

Hooks make the code messier:

const { posts } = useQuery()

<div>
// It's ambiguous what 'posts' is relating to, especially if we're calling it with arguments
{posts({ limit: 1 }).map()}
// It's super-clear when you don't have the hook
{query.posts({ limit: 1 })}

// if you want to use a field with the same arguments multiple times
// we need to store it as a variable
const posts_ = posts({ limit: 1 })
// but the name conflicts with `const { posts } = useQuery()`

// so we'd be better of with doing
const query = useQuery()
const posts = query.posts({ limit: 1 })
{posts.map()}

// but then the hook is redundant, we could of just imported `query` from `../src/gqless`
</div>

It's possible to detect whether we're rendering inside a React Component by doing

try {
    var inComponent = true
    React.useState("")
} catch(e) {
    inComponent = false
}
console.log(inComponent)

As GQless is a proxy, we could easily do this when you do query.posts. This shouldn't be in the core though, so the core could expose an API:

// somewhere in the react binding
import { interceptRootProxy } from 'gqless'

interceptRootProxy((type: "subscription" | "query") => {
  // called when `query.XXX` is accessed
})

inside this API, we could perform all the hook logic we currently do inside useQuery / useSubscription.

useSubscription doesn't have any arguments to customize, so it could be removed. useQuery has optional arguments, so we should make it require you to pass options

I think this should work, I'm curious to hear your thoughts

natew commented 3 years ago

I agree on usage, in general moving away from destructuring on the hooks in docs and as a general good practice, like you said:

const query = useQuery()
query.posts()

The hookless thing looks a bit crazy to me, but perhaps Pablo doesn't see any big downsides.

vicary commented 3 years ago

Does this issue means React users has to move away from the hook pattern?

PabloSzx commented 3 years ago

Does this issue means React users has to move away from the hook pattern?

I don't think so


I don't agree with the proposal made here, there is component-aware stuff in the hooks, and non-suspense usage, which this pattern wouldn't allow at all

@samdenty If you want to make a separate branch implementing this logic as a proof of concept, feel free, but removing the hooks is 100% unlikely