I am creating a simple weather app to solidify my react hook knowledge. When using useEffect I keep coming up with an error when using async await functions. I looked around and found ways around to use async functions one time in use effect.
My problem is that I want to use async/await functions twice. I use navigator.geolocation to find current location and set lat and long in state. Then, once they are set run a weather api that uses the new state of lat and long. I found multiple solutions on here about how setting state waits til the next render so using the newly set state in the next fetchAPI function wont work.
Thus, I came up with this solution.
const [lat, setLat] = useState([]);
const [long, setLong] = useState([]);
const [data, setData] = useState();
useEffect(() => {
fetchLocation(/*uses navigator.geolocation to setLong and setLat*/);
// hacked out a way to not call fetch data until lat and long are set.
if (typeof lat == "number" && typeof long == "number") {
fetchWeatherData();
}
console.log(lat, "<= lat");
console.log(long, "<= long");
}, [lat, long]);
This solution works like I wanted on localhost because it only fetches the weatherAPI when the lat and long states are set with the first function. Before useEffect would load the weatherAPI with lat and long still set to empty causing an error. I am wondering if this is correct way to go about this problem or if there are unknown side effects that I haven't found yet.
Also this warning pops up afterwards and I am not sure if how to handle it.
"src/App.js Line 37:6: React Hook useEffect has a missing dependency: 'fetchWeatherData'. Either include it or remove the dependency array react-hooks/exhaustive-deps"
EDIT: full code as requested from comments
import React, { useState, useEffect } from "react";
import WeatherDisplay from "./weather";
require("dotenv").config();
function App() {
const [lat, setLat] = useState([]);
const [long, setLong] = useState([]);
const [data, setData] = useState();
const fetchLocation = () => {
navigator.geolocation.getCurrentPosition((position) => {
setLat(position.coords.latitude);
setLong(position.coords.longitude);
});
};
const fetchWeatherData = () => {
fetch(
`${process.env.REACT_APP_API_URL}/weather/?lat=${lat}&lon=${long}&units=metric&APPID=${process.env.REACT_APP_API_KEY}`
)
.then((res) => res.json())
.then((result) => {
setData(result);
console.log(result);
});
};
useEffect(() => {
fetchLocation();
// hacked out a way to not call fetch data until lat and long are set.
if (typeof lat == "number" && typeof long == "number") {
fetchWeatherData();
}
console.log(lat, "<= lat");
console.log(long, "<= long");
}, [lat, long]); // set as empty arrays if locations don't work
return (
<div className="App">
{/* data is the data that was fetched from fetchWeatherData() */}
<WeatherDisplay weatherData={data} />
</div>
);
}
export default App;