#javascript #reactjs #react-hooks #fetch
#javascript #reactjs #реагирующие хуки #выборка
Вопрос:
В react js я извлекаю данные из нескольких API, и мне нужно извлекать их один за другим, а также вызывать некоторые функции по очереди, поэтому я использовал react state с операторами if, чтобы заставить их работать. Я изменяю состояние разных useState
переменных после выполнения одной выборки или конкретной функции, но даже при изменении состояния функции не выполняются. Весь код находится внутри другой функции, но я его не предоставил. В fetchData
функции я хочу запускать функции и выборки синхронно, но они не выполняются
let [origData, setOrigData] = useState(null);
let [imageId, setImageId] = useState([]);
let [myItems, setMyItems] = useState([]);
let [finalData, setFinalData] = useState([]);
let [getData, setGetData] = useState(false);
let [itemId, setItemId] = useState(false);
let fetchData = () => {
fetch('http://127.0.0.1:8000/api/get-order-item/' sessionStorage.getItem('id'), {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer' ' ' sessionStorage.getItem('token'),
},
})
.then((response) => {
return response.json();
})
.then((data) => {
if (data) {
setMyItems(data);
setGetData(true);
}
});
if (getData === true) {
myItems.map((e) => {
console.log(e);
});
setItemId(true);
}
if (itemId === true) {
fetch('http://127.0.0.1:8000/api/data')
.then((response) => {
return response.json();
})
.then((info) => {
setOrigData(info);
console.log('fetch done');
});
}
};
Ответ №1:
React не предназначен для синхронного запуска. Рендеринг представления имеет приоритет и не должен блокироваться каким-либо кодом, который в первую очередь не имеет отношения к представлению. Концепция запуска кода, блокирующего просмотр, такова useEffect
. Вы получаете представление об использовании API-интерфейсов при объяснении useEffect
Ответ №2:
Причина, по которой это не работает, заключается в том, что данные состояния устанавливаются в функциональном блоке. Нет причин, по которым вам нужно это состояние для отправки второго запроса, когда у вас есть данные из первого ответа!
Кроме того, response.json()
это обещание и должно быть разрешено!
Я переработал ваш код, чтобы его было легче выполнять с помощью async / await.
const fetchData = async() => {
const response = await fetch('http://127.0.0.1:8000/api/get-order-item/' sessionStorage.getItem('id'), {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer' ' ' sessionStorage.getItem('token')
}
})
const data = await response.json();
if(data) {
setMyItems(data)
/// setGetData(true) <- dont need
data.forEach(
(e) => {
console.log(e) // <- why are you logging every item?
}
)
const infoResponse = await fetch('http://127.0.0.1:8000/api/data')
const infoData = await infoResponse.json();
setOrigData(infoData)
console.log('fetch done')
}
}
useEffect(() => {
(async() => {
await fetchData()
})()
}, [])
Комментарии:
1. Следует также отметить, что такого рода согласование запросов должно выполняться вашим сервером. Это лучшая практика, поскольку она быстрее, безопаснее и повысит производительность вашего приложения, поскольку запросы в браузере являются дорогостоящими с точки зрения производительности.
2. Спасибо, сэр, за вашу помощь