#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",
Теперь это успешно позволило получить данные, как я и ожидал.