DEV Community

Discussion on: No, disabling a button is not app logic.

Collapse
 
gafemoyano profile image
Felipe Moyano

Thanks for the article David, it was very well thought out. I was wondering how this approach would work when using something like Apollo's useQuery hook to fetch data.

My initial approach was to assume my component would start on a 'loading' state. It might not be necessarily true, but it seems to work since the first pass of the render cycling useQuery will return a loading value set to true.

useQuery provides a prop for an onComplete function, so that seemed like a good place to call dispatch({type: "RESOLVE", data}) and let the reducer do some work and put the data into the state.
And this seemed to work fine for the most part. However, I bumped into a problem when some other component updated data via mutation. Turns out that onComplete will, understandably, only run the first time the query is completed. But apollo apparently does some magic to notify data that something mutated it, updates it, and triggers a render.

The example goes something like this:
You get a user and its credit cards from use query:

const {loading, data, error} = useQuery()
// data.user = { user:  {id: 1, creditCards: []} 
Then somewhere else the user adds a credit card via useMutation()
// magically data.user is now { user: {id: 1, creditCards: [{id:1}] }
Enter fullscreen mode Exit fullscreen mode

So even though I could send the newly added credit card on a dispatch call, and update the state accordingly, it kind of feels like i'd be maintining two sources of truth. Whatever apollo's useQuery returns and what I've manually placed on the Store.

Anyways, all of this is to say... how would you make this work with Apollo? Are the approaches at odds, or am I making the wrong kind of assumptions on how to handle the response?

Cheers, and thanks again for writing this up.

Collapse
 
karfau profile image
Christian Bewernitz

We also had this question recently and decided to decouple queries and mutations from the state machines where possible.
In the end the appollo hooks implement their own "state machines" in a way.

It's an ongoing process to convert the existing code, but we are convinced that it's the right approach for us.