Как обрабатывать несколько экземпляров axios

Я сделал хук под названием useAxios, где я получаю свой токен из состояния, а затем использую его для создания экземпляра Axios:

export const useAxios = () => {
  
  const { userData } = useUser();

  const customAxios = axios.create({
    headers: { Authorization: `Bearer ${userData?.user?.token}` },
  });
  
  return customAxios;
};

Но теперь я беспокоюсь, что, используя этот хук в нескольких компонентах, я создам много экземпляров Axios! поэтому мои вопросы:

  1. как я могу проверить, создан ли еще один экземпляр, и каждый раз, когда я просто перезаписываю его ИЛИ я фактически создаю несколько экземпляров?

  2. в случае, если это несколько экземпляров, это нормально?

  3. Я могу использовать useEffect или useCallback, чтобы он создавался только при изменении токена, но есть ли для этого какое-либо другое распространенное решение?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
102
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Во-первых, когда вы используете этот хук в любом компоненте, экземпляр axios будет создаваться каждый раз, когда вы его вызываете, не перезаписывая предыдущий из-за вашей реализации, он должен создавать экземпляр и возвращать его, поэтому нет абсолютно никакого смысла, чтобы он переопределял какой-то предыдущий, потому что на самом деле предыдущих нет!

Итак, как решить эту проблему?

в основном не создавайте экземпляр внутри хука, вместо этого получите к нему доступ.

создайте экземпляр вне хука и получите доступ к нему внутри хука и делайте с ним все, что хотите.

это заставит хук просто манипулировать экземпляром, не создавая его

Как узнать, создаю ли я несколько экземпляров?

пока вы следуете этому подходу, вы определенно создаете несколько экземпляров, на самом деле, я не знаю конкретного способа узнать, создаю ли я несколько экземпляров или, может быть, он не присутствует в моем уме в настоящее время, но для меня , очевидно, что этот подход создаст несколько экземпляров.

Если это несколько экземпляров, это нормально?

на этот вопрос нет правильного ответа, если это не противоречит вашей логике (идее) или/и производительности, так что все в порядке, но я думаю, что это сделает ваш код совершенно неконтролируемым или создаст несколько экземпляров с разными конфигурациями. хорошо, потому что это заставит вас потеряться (я не уверен, я просто думаю.)

Я могу использовать useEffect или useCallback, чтобы он создавался только при изменении токена, но есть ли для этого какое-либо другое распространенное решение?

что-то не так с вашим вопросом, который «создан», я не понимаю, вы хотите воссоздавать его каждый раз при изменении токена?

ладно возможно это не лучший вариант т.к. axios предоставляет некую внутреннюю методологию позволяющую менять токен в заголовке, которые являются перехватчиками

они очень похожи на промежуточное ПО по методологии (если вы знакомы с промежуточным ПО), они работают следующим образом:

  • 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, когда он мне нужен.

Другие вопросы по теме