I'm a bit baffled here. According to this SO question and also this question, I should be able to call the useEffect hook after calling the useQuery hook to populate state, which I am doing via useReducer. E.g., something like this (assume that foo, bar, and baz are named queries within a single request to the GraphQL server):
const MyComponent = ( props ) => {
const [ state, dispatch ] = useReducer( reducer, initialState )
const query = someCondition ? query1 : query2
const variables = { variables: someCondition ? query1Vars : query2Vars }
const { loading, error, data } = useQuery( query, variables )
useEffect(function() {
dispatch({
type: types.INIT,
payload: {
foo: data.foo,
bar: data.bar,
baz: data.baz
}
})
}, [data])
return (
<div>
{
(() => {
if ( loading ) return <Loading />
if ( error ) return <Error />
return (
// components that depend on data
)
})()
}
</div>
)
}
For reasons I can't determine, data is undefined when I reference it inside useEffect. I have checked my network responses and the call to my GraphQL endpoint is indeed returning data. (Essentially, what's described in this other SO question about useQuery.)
Except for the conditional query/variable assignment, this code is in use for some of our other components and it works fine, so I have no idea why it's not working in my case.
I'm not sure what's going on here, as I've made sure that no hooks are being called conditionally, in violation of the rules of hooks; all I'm doing is conditionally assigning variable values before sending the query via Apollo client. (I also tried the onCompleted property of the useQuery options, without the useEffect hook, but to no avail; data is still undefined.)
useEffectwill always fire beforeuseQueryhas completed, what I would expect is thatuseEffectwould trigger twice, once when the component mounts and then secondly whenuseQueryreturns a result. Seems to me that you aren't accounting for the initialuseEffectcall whendatahas yet to be set.if ( data ) { ... }doesn't seem to account for the initial firing of theuseEffecthook. github.com/trojanowski/react-apollo-hooks/issues/158 seems to suggest you don't need to useuseEffectat all, but I've seen that code working previously. How should the initial render be handled?useQueryalready stores the state for you - however I've no idea of your use case, only going off the code you provided where you want to get it into some form of reducer.datawill be initially undefined as @James pointed out. It can also be undefined indefinitely if network errors are encountered. That said, there's little reason to ever do this --useQueryalready manages state for you. If you need to further transform this state, then you just do so as regular variables inside your component.onCompletedcallback foruseQuery, but I see so many examples ofuseQuery+useEffectthat I was certain it should work as described, or least not be actively problematic. :)