#javascript #reactjs #axios
#javascript #reactjs #axios
Вопрос:
Я работаю над небольшим проектом, который включает в себя получение погоды в разных местах, а также динамическое получение времени в этих местах впоследствии. Все это работало нормально, но затем я попытался сделать еще один шаг вперед, пытаясь обновлять данные, полученные из API каждую минуту (без повторной отправки / нажатия клавиши enter). Я пробовал различные способы реализации функции setinterval в коде, но, похоже, ни один из них не работает. Вот как выглядит код:
function App() {
const [query, setQuery] = useState("");
const [weather, setWeather] = useState({});
const [timeZone, setTimeZone] = useState({});
const handleChange = (e) => {
setQuery(e.target.value);
};
const apiCall = () => {
Axios({
method: "get",
url: `${api.timeBase}apiKey=${api.timeKey}amp;location=${query}`,
timeout: 10000,
})
.then((res) => {
console.log(res.data);
setWeather(res.data);
//setQuery("");
})
.catch((err) => {
console.log(err);
});
};
const handleSubmit = (e) => {
e.preventDefault();
apiCall();
};
useEffect(() => {
setInterval(apiCall, 60000);
}, []);
useEffect(() => {
if (weather.main !== undefined) {
Axios.get(
`${api.timeBase}apiKey=${api.timeKey}amp;location=${weather.name}, ${weather.sys.country}`
)
.then((res) => {
console.log(res.data);
setTimeZone(res.data);
})
.catch((err) => {
console.log(err);
});
}
}, [weather]);
По сути, проблема, с которой я сталкиваюсь больше всего, заключается в том, что где-то внутри функции setinterval query
параметр очищается, и API продолжает извлекать другое местоположение, пока не вернется к нормальному состоянию. я попытался предотвратить query
очистку параметра после обновления состояния, но это не помогло.
PS: мне пришлось разбить handlesubmit
, потому что прикрепление setinterval к исходному блоку кода вызывает ошибку, вызывающую e.preventDefault не определено. Кроме того, я думаю, что вызов setInterval без useEffect также делает ситуацию намного хуже.
Комментарии:
1. Я думаю, что он должен обновлять данные, потому что useEffect вызывает ApiCall функцию каждую минуту точно. Должна быть какая-то другая проблема
Ответ №1:
Очистите интервал после завершения интервала. setInterval
Функция возвращает a timerId
, который в противном случае должен быть удален, он остается в пуле таймеров и может выполняться даже после запуска экземпляра обратного вызова.
React.useEffect(() => {
const id = setInterval(apiCall, 60000);
return () => clearInterval(id);
}, []);
Комментарии:
1. я думаю, что я на самом деле только что решил это сейчас. я передал в
query
качестве зависимости useEffect, который имеет setInterval . кажется, все работает так, как ожидалось. ух ты!