Q:

Should we always use a hook or is it ok to directly call it from the client? 

In React, we can use the useMutation or useQuery inside components.  But let's say we want to run the query or the mutation inside a helper file (Let's say we extract the part where we format the data and execute the mutation to a helper function away from the component function).  In here, we have two options:

Pass the mutation function obtained from useMutation to the helper function
Call the mutation directly inside the helper function like apolloClient.mutate

What is the most recommended way of doing things and what do you recommend? 

A:

The hooks expose additional component state for the returned data, loading state and error state.  This is really just a convenience because it means you don't have to call useState yourself.  As such, it's perfectly fine to use client.mutate if you don't need to keep track of those states.  In a sense, it may be better since you're not needlessly using memory for variables you won't use anyway. 
The same could be said for useQuery, which really just uses client.watchQuery under the hood and saves you from having to use useState and useEffect.