I'm writing a custom hook to fetch some enums defined in my GraphQL schema for use in form fields. The enum values obviously don't change all that frequently but I wanted to make them available to any form component (or any component). My problem is that no matter how I fire the query, my hook is always returning its initial state. There are several examples of data fetching in custom hooks, and they all follow a pretty similar pattern, e.g., something like this answer: Fetch data with a custom React hook
I first wrote the hook to use Apollo's useQuery()
, and I set data
as a dependency of useEffect()
.
export const useFormFieldEnums = () => {
const [ enums, setEnums ] = useState( null )
const ENUMS_QUERY = gql`
query FormFieldEnums {
mailingAddressTypes: __type(name: "MailingAddressType") {
name
enumValues {
name
}
}
emailTypes: __type(name: "EmailType") {
name
enumValues {
name
}
}
phoneTypes: __type(name: "PhoneType") {
name
enumValues {
name
}
}
}
`
const { data } = useQuery( ENUMS_QUERY )
useEffect(() => {
if ( data ) {
// result = wrangle data into desired shape
setEnums( result )
}
}, [data])
return enums
}
Done this way, the query is dispatched (I see the request and response in the browser's network tab), but return enums
isn't executed again after the query resolves with data.
I thought that perhaps the data
dependency of useEffect()
was responsible, so I tried using the query()
method of Apollo Client directly, via the useApolloClient()
hook, to allow the query to be dispatched asynchronously and have no dependencies for useEffect()
. Done this way, the query doesn't even appear to be executed. (?)
export const useFormFieldEnums = () => {
const [ enums, setEnums ] = useState( null )
const client = useApolloClient()
const ENUMS_QUERY = gql`
query FormFieldEnums {
mailingAddressTypes: __type(name: "MailingAddressType") {
name
enumValues {
name
}
}
emailTypes: __type(name: "EmailType") {
name
enumValues {
name
}
}
phoneTypes: __type(name: "PhoneType") {
name
enumValues {
name
}
}
}
`
useEffect(async() => {
try {
const { data } = await client.query({ query: ENUMS_QUERY })
// result = wrangle data into desired shape
setEnums( result )
} catch ( error ) {
console.error( error )
}
}, [])
return enums
}
In both cases I'm always getting the initial state of enums
back from the hook, even though return enums
should be executed each time the value of enums
changes. Presumably, setEnums( result )
is not getting called, but I can't figure out why.
Any help is appreciated, thanks!