I wrote a util wrapper for an API I'd like to consume. The wrapper handles request buidling and token fetching.
import refreshToken from './refreshToken'
/**
 * Fetch util handles errors, tokens and request building for the wrapped API calls
 * @param {string} url Request URL e.g. /chargehistory
 * @param {string} requestMethod Request Method [GET, POST, PUT, DELETE]
 * @param {object} requestBody Request Body as JSON object
 * @param {object} retryFn The caller function as object reference to retry
 * @private This function is only used as util in this class
 * @async
 */
const fetchUtil = (url, requestMethod, requestBody, retryFn) => {
    // Block thread if the token needs to be refetched
    if(sessionStorage.getItem('token') == null || Number(sessionStorage.getItem('token_expiration')) < new Date().getTime()) {
        refreshToken()
    }        
    let request = {
        method: requestMethod,
        headers: {
            'Authorization': `Bearer ${sessionStorage.getItem('token')}`,
            'Content-Type': 'application/json'
        }
    }
    if(requestMethod === 'POST' || requestMethod === 'PUT') {
        request.body = JSON.stringify(requestBody)
    }
    fetch(`${process.env.REACT_APP_API}${url}`, request)
    .then(response => {
        if(response.ok) {
            return response.json()
        } else if(response.status === 401) {
            refreshToken().then(() => retryFn())
        } else {
            console.error(`Error on fetching data from API: ${response.status}, ${response.text}`)
        }
    })
    .then(json => {
        console.log(json)
        return json
    })
    .catch(error => console.error(error))
}
This works and prints some json to the console once it is resolved. Next I built functions to consume utilize this abstraction:
/**
 * Get a list of all completed charge sessions accessible by the current user matching the filter options.
 */
const getChargehistory = (installationId) => {
    console.log(fetchUtil(`/chargehistory?options.installationId=${installationId}`, 'GET', {}, getChargehistory))
}
Which prints undefined I can somewhat understand that although I did expect a function reference or a promise.
I tried adding async before the fetchUtil and the caller and await the fetchUtil. This gave me an error to not calling await on undefined. I also tried reweriting it into a hook which did not work at all.
I would need the data in the useEffect hook of a component:
const Cockpit = () => {
    const { t } = useTranslation()
    const [chargehistory, setChargehistory] = useState(undefined)
    const [installationreport, setInstallationreport] = useState(undefined)
    useEffect(() => {
        setChargehistory(getChargehistory)
        setInstallationreport(getInstallationreport)
    }, [])
}
Why am I getting undefined and how can I resolve this?
 
    