#javascript #reactjs #axios #react-hooks
#javascript #reactjs #axios #реагирующие крючки
Вопрос:
Экземпляр axios еще не готов к рендерингу, поскольку я получаю сообщение об ошибке «Не удается прочитать свойство’get’ неопределенного», НО ветви загружены, так что, по-видимому, следующая попытка завершается успешно.
Экземпляр axios в 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;
};
Ошибка в компоненте ‘Registration’:
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]);
...
Сначала у меня все работало без ошибок с аналогичной fetch
функцией, поэтому кажется, что экземпляр axios (который импортируется) является виновником. Я также нахожу немного странным, что я не могу этого сделать:
useEffect(() => {
loadBranches();
}, []);
как тогда я получаю 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
это было не так при использовании выборки …, и для имитации «при монтировании» вы обычно используете [] .
Как я могу убедиться axiosInstance
, что оно существует при монтировании?
Комментарии:
1. это асинхронно, значит, вам нужно подождать. Вы просто проверяете, готов ли axiosInstance перед его использованием.
2. кажется, что функция очистки useEffect вызывается, хотя она удаляется! один вопрос, зачем использовать функцию очистки?
3. @SomeoneSpecial Хорошо, как мне это сделать?
4. @SadhilSpring Когда я комментирую функцию очистки в
useAxios
проблеме, она остается.
Ответ №1:
Вы можете сделать это проще :
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 amp;amp; loadBranches(); // <== here
}, [loadBranches, axiosInstance]);
Он будет вызывать функцию loadBranches только тогда, когда определен axiosInstance.
Ответ №2:
Вам нужно заставить его подождать, пока axiosInstance
не будет определено, например, следующим образом:
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]
);
...
Теперь компонент загружается нормально, без ошибки, и правильно запускает axios.
Комментарии:
1. Можно ли также «заставить его ждать» внутри
hooks.js
, сделав это обещанием или чем-то еще …?! Это позволит сохранить мониторинг состояния, где бы оно ни использовалось.