react-запрос: useQuery возвращает неопределенное значение, и компонент не выполняет повторную отправку

#reactjs #typescript #axios #react-query

Вопрос:

Я играю с reactQuery небольшим демонстрационным приложением, которое вы можете увидеть в этом репо. Приложение вызывает этот макет API.

Я застрял на проблеме, когда я использую useQuery крючок для вызова этой функции в файле API продукта:

 export const getAllProducts = async (): Promise<Product[]> => {
  const productEndPoint = 'http://localhost:5000/api/product';
  const { data } = await axios.get(productEndPoint);
  return data as Array<Product>;
};
 

В моем ProductTable компоненте я затем вызываю эту функцию с помощью:

 const { data } = useQuery('products', getAllProducts);
 

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

Если я отлаживаю, я вижу, что объект данных, возвращаемый useQuery, не определен.

Веб-запрос успешно завершен, и я вижу, что данные возвращаются на вкладке «Сеть» в разделе «Запросы» в браузере.

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

Кто-нибудь может подсказать, где IO может пойти не так, пожалуйста?

Комментарии:

1. Извините, что я неправильно истолковал код. Можете ли вы подготовить с axios-mock-adapter помощью codesandbox ?

2. Ип, спасибо, я попробую настроить что-нибудь на неделе, когда вы это сделаете. Спасибо.

Ответ №1:

Просто используйте вот так

 export const getAllProducts = async (): Promise<Product[]> => {
  const productEndPoint = 'http://localhost:5000/api/product';
  const res= await axios.get(productEndPoint);
  return res.data as Array<Product>;
};

const { data:products , isLoading } = useQuery('products', getAllProducts);

if(isLoading){
return <FallBackView />
}

return (){
products.map(item => item)
}
 

Комментарии:

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

Ответ №2:

Мне удалось заставить это работать. Ради блага других я поделюсь своими знаниями:

Я внес несколько небольших изменений, начиная с моей функции api. Изменение функции на следующую:

 export const getAllProducts = async (): Promise<Product[]> => {
   const response = await axios.get(`api/product`, {
     headers: {
       Accept: 'application/json',
       'Content-Type': 'application/json',
     },
 });

  return response.data as Product[];
};
 

Я не создаю ответ на axios вызов, а скорее беру из него объект данных и возвращаю его как продукт[]

Затем второе, что я затем изменил, было в моем ProductTable компоненте. Здесь я рассказал useQuery , какого типа ответа следует ожидать, изменив вызов на :

 const { data } = useQuery<Product[], Error>('products', getAllProducts);
 

Наконец, ошибка новичка с моей стороны: потому что я использовал макет api в контейнере docker, работающем на локальном хосте, и вызывал его с помощью http://localhost:5000/api/product Я получал общеизвестную сетевую ошибку:

локальный хост заблокирован политикой CORS: заголовок «Управление доступом-Разрешить-Происхождение» отсутствует…

Поэтому, чтобы обойти это для целей данного упражнения, я просто добавил свойство в пакеты.файл json: "proxy":"http://localhost:5000",

Теперь это успешно позволило получить данные, как я и ожидал.