Reputation: 13383
The axios instance is not yet ready upon render as I get the error "Cannot read property 'get' of undefined", BUT the branches are loaded, so apparently next attempt succeeds.
The axios instance in hooks.js
:
import {useState, useEffect} from 'react';
import axios from 'axios';
import {useKeycloak} from '@react-keycloak/web';
import {BASE_URL} from '../constants.js';
export const useAxios = () => {
const {keycloak, initialized} = useKeycloak();
const [axiosInstance, setAxiosInstance] = useState({});
useEffect(() => {
const instance = axios.create({
baseURL: BASE_URL,
headers: {
Authorization: initialized ? `Bearer ${keycloak.token}` : undefined,
},
});
setAxiosInstance({instance});
return () => {
setAxiosInstance({});
}
}, [keycloak, initialized, keycloak.token]);
return axiosInstance.instance;
};
The error is in the 'Registration' component:
import {useAxios} from "../utilities/hooks";
const Registration = () => {
const {initialized} = useKeycloak();
const axiosInstance = useAxios();
const [branches, setBranches] = useState({});
const loadBranches = useCallback(async () => {
try {
const response = await axiosInstance.get('/branch');
setBranches(response.data);
} catch (error) {
console.log(`Error when loading branches: ${error.message}`, error);
}
}, [axiosInstance]);
useEffect(() => {
loadBranches();
}, [loadBranches]);
...
I first had things working without errors with a similar fetch
function, so it seems the axios instance (which is imported) is the culprit. I find it also a bit strange that I can not do:
useEffect(() => {
loadBranches();
}, []);
as then I get React Hook useEffect has a missing dependency: 'loadBranches'. Either include it or remove the dependency array react-hooks/exhaustive-deps overrideMethod @ react_devtools_backend.js:2430 printWarnings @ webpackHotDevClient.js:138 handleWarnings @ webpackHotDevClient.js:143 push../node_modules/react-dev-utils/webpackHotDevClient.js.connection.onmessage @ webpackHotDevClient.js:210
this was not the case when using fetch..., and to simulate a 'when mounted' you'd normally use [].
How can I ensure axiosInstance
exists at mount?
Upvotes: 0
Views: 1269
Reputation: 3176
You can make it simpler :
const Registration = () => {
const axiosInstance = useAxios();
const [branches, setBranches] = useState({});
const loadBranches = useCallback(async () => {
try {
const response = await axiosInstance.get('/branch');
setBranches(response.data);
} catch (error) {
console.log(`Error when loading branches: ${error.message}`, error);
}
}, [axiosInstance]);
useEffect(() => {
axiosInstance && loadBranches(); // <== here
}, [loadBranches, axiosInstance]);
It will only invoke the loadBranches function when the axiosInstance is defined.
Upvotes: 1
Reputation: 13383
You need to make it wait till axiosInstance
is defined, e.g. as follows:
const Registration = () => {
const axiosInstance = useAxios();
const [branches, setBranches] = useState({});
const [axiosReady, setAxiosReady] = useState(false);
const loadBranches = useCallback(async () => {
try {
if (axiosReady) {
const response = await axiosInstance.get('/branch');
setBranches(response.data);
}
} catch (error) {
console.log(`Error when loading branches: ${error.message}`, error);
}
}, [axiosReady, axiosInstance]);
useEffect(() => {
if (axiosInstance) {
setAxiosReady(true);
}
}, [axiosInstance]);
useEffect(() => {
loadBranches();
}, [loadBranches]
);
...
The component loads fine without the error now and properly triggers axios.
Upvotes: 0