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

Document the `load` function #41

Closed Grsmto closed 4 years ago

Grsmto commented 4 years ago

Hi, First of all, thanks for this great library. Using it on my latest project and it's been great so far.

I'm currently building a "search" functionality that naturally requires imperative graphQL query to be achieved: user fills an input then the fetch is triggered. I found the load method that's returned from useGraphQL in the issues. Is that undocumented on purpose? Or is it just missing?

Would you accept a PR for this? It could come along with a code example.

Thanks!

mike-marcacci commented 4 years ago

Hi @Grsmto,

You probably don't need to use any of the imperative functionality in this library. Simply using react's state management should be totally sufficient.

Try something like this (totally untested, just as a point in the right direction):

function SomeComponent {
  // This is the value shown in the input.
  const [inputValue, setInputValue] = useState("");

  // This is the value used in the query. It's updated when the user clicks the "Search" button.
  const [searchTerm, setSearchTerm] = useState("");

  const { loading, cacheValue = {} } = useGraphQL({
    loadOnMount: searchTerm.length > 0,
    operation: {
      query: `query SearchQuery ($term: String!) { search(term: $term) { name } }`,
      variables: {
        term: searchTerm
      }
    }
  })

  return (
    <div>
      <form onSubmit={e => setSearchTerm(inputValue)}>
        <input type="search" value={inputValue} onChange={e => setInputValue(e.target.value)} />
        <input type="submit" value="Search" />
      </form>

      <div>
        {cacheValue.data?.search?.map(v => <div>{v.name}</div>)}
      </div>
    </div>
  );
}
Grsmto commented 4 years ago

Great stuff! So the trick here is that loadOnMount is not actually only "on mount" but on every render. Which I didn't know! loadOnRender would make more sense in that case I suppose.

Feel free to close this since I suppose it's better to insentivise the reactive approach instead of imperative one.

mike-marcacci commented 4 years ago

I agree – it's not quite loading on render either though... perhaps something not tied to a lifecycle event would be more clear? Perhaps autoLoad or such?