I am working on a little project that involves getting the weather at different locations and also, dynamically getting the time at those locations afterwards. All these worked fine but then i tried to take it a step further by attempting to refresh the data gotten from the API every minute(without resubmitting/pressing the enter key). I've tried various ways of implementing the setinterval function into the code but none seem to work. Here is what the code looks like:
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}&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}&location=${weather.name}, ${weather.sys.country}`
)
.then((res) => {
console.log(res.data);
setTimeZone(res.data);
})
.catch((err) => {
console.log(err);
});
}
}, [weather]);
Basically, the issue i get the most is that somewhere within the setinterval function, the query
parameter is cleared and the API continues to retrieve a different location till gets back to normal. i tried preventing the query
parameter from clearing after it updates the state, that didnt help.
PS: i had to breakdown the handlesubmit
because attaching the setinterval to the original block of code throws an error cause e.preventDefault isn't defined. Also, I think calling the setInterval without the useEffect makes things a lot worse too.
Clear out the interval after the interval is finished. The setInterval
function returns a timerId
that should be cleared out otherwise, it remains in the timer pool and can execute even after the instance of the callback has been run.
React.useEffect(() => {
const id = setInterval(apiCall, 60000);
return () => clearInterval(id);
}, []);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With