Я сделал хук под названием useAxios, где я получаю свой токен из состояния, а затем использую его для создания экземпляра Axios:
export const useAxios = () => {
const { userData } = useUser();
const customAxios = axios.create({
headers: { Authorization: `Bearer ${userData?.user?.token}` },
});
return customAxios;
};
Но теперь я беспокоюсь, что, используя этот хук в нескольких компонентах, я создам много экземпляров Axios! поэтому мои вопросы:
как я могу проверить, создан ли еще один экземпляр, и каждый раз, когда я просто перезаписываю его ИЛИ я фактически создаю несколько экземпляров?
в случае, если это несколько экземпляров, это нормально?
Я могу использовать useEffect или useCallback, чтобы он создавался только при изменении токена, но есть ли для этого какое-либо другое распространенное решение?
Во-первых, когда вы используете этот хук в любом компоненте, экземпляр axios будет создаваться каждый раз, когда вы его вызываете, не перезаписывая предыдущий из-за вашей реализации, он должен создавать экземпляр и возвращать его, поэтому нет абсолютно никакого смысла, чтобы он переопределял какой-то предыдущий, потому что на самом деле предыдущих нет!
в основном не создавайте экземпляр внутри хука, вместо этого получите к нему доступ.
создайте экземпляр вне хука и получите доступ к нему внутри хука и делайте с ним все, что хотите.
это заставит хук просто манипулировать экземпляром, не создавая его
пока вы следуете этому подходу, вы определенно создаете несколько экземпляров, на самом деле, я не знаю конкретного способа узнать, создаю ли я несколько экземпляров или, может быть, он не присутствует в моем уме в настоящее время, но для меня , очевидно, что этот подход создаст несколько экземпляров.
на этот вопрос нет правильного ответа, если это не противоречит вашей логике (идее) или/и производительности, так что все в порядке, но я думаю, что это сделает ваш код совершенно неконтролируемым или создаст несколько экземпляров с разными конфигурациями. хорошо, потому что это заставит вас потеряться (я не уверен, я просто думаю.)
что-то не так с вашим вопросом, который «создан», я не понимаю, вы хотите воссоздавать его каждый раз при изменении токена?
ладно возможно это не лучший вариант т.к. axios предоставляет некую внутреннюю методологию позволяющую менять токен в заголовке, которые являются перехватчиками
они очень похожи на промежуточное ПО по методологии (если вы знакомы с промежуточным ПО), они работают следующим образом:
это дает вам возможность убедиться, что токен действителен, и если это не так, вы сделаете запрос на сервер, чтобы получить новый, затем добавьте его в заголовки, затем продолжите запрос, это мой код, который я Я использую его в своем текущем проекте для проверки токена при каждом запросе.
let accessToken = localStorage.getItem("access")
? JSON.parse(localStorage.getItem("access") ?? "")
: "";
const refreshToken = localStorage.getItem("refresh")
? JSON.parse(localStorage.getItem("refresh") ?? "")
: "";
axiosInstance.interceptors.request.use(async (req) => {
if (!accessToken) {
accessToken = localStorage.getItem("access")
? JSON.parse(localStorage.getItem("access") ?? "")
: null;
req.headers!.Authorization = `Bearer ${accessToken}`;
}
const user: any = jwt_decode(accessToken);
const isExpired = dayjs.unix(user.exp).diff(dayjs()) < 1;
if (!isExpired) return req;
const response = await axios.post(`${API_BASE_URL}/auth/refresh/`, {
refresh: refreshToken,
});
localStorage.setItem("access", JSON.stringify(response.data.access));
localStorage.setItem("refresh", JSON.stringify(response.data.refresh));
req.headers!.Authorization = `Bearer ${JSON.parse(response.data.access)}`;
return req;
});
конечно, я использовал некоторые внешние библиотеки, и код довольно сложный, но если вы проведете исследование, вы увидите, что это намного проще и лучше, чем использование useEffect.
useEffect
и useCallback
для этого?определенно, вы можете это сделать, но я не вижу этого хорошего решения (по моему личному мнению)
если вы видите, что мой ответ не был хорошим и / или недостаточно ясным, оставьте комментарий, и давайте обсудим, о чем вы думаете.
благодаря предложению @Youssef_Ayman168 я нахожу это решение:
axios.interceptors.request.use(
(config) => {
const token = JSON.parse(localStorage.getItem(USER))?.token;
if (token) {
config.headers["Authorization"] = "Bearer " + token;
}
// config.headers['Content-Type'] = 'application/json';
return config;
},
(error) => {
console.info({ error });
Promise.reject(error);
}
);
export { axios };
а затем я просто импортирую этот экземпляр Axios, когда он мне нужен.