this is my first time using react. im working on a basic weather app. i have a problem with using multiple useEffect hook in order. i need to fetch both the geolocation and then the weather APP api in order when the page load. but i the location keep returning null, here's the code
useEffect(()=>{
navigator.geolocation.getCurrentPosition((position) => {
setLatitude(position.coords.latitude)
setLongitude(position.coords.longitude)
});
},[])
useEffect(()=> {
axios.get(`${api.base}weather?lat=${latitude}&lon=${longitude}&units=metric&appid=${api.key}`).then
((response) => {
console.log(response.data)
})
},[])
any solution will be appreciated. thank you
CodePudding user response:
For this you could make the second useEffect dependent on your latitude and longitude states:
useEffect(()=>{
axios.get(`${api.base}weather?lat=${latitude}&lon=${longitude}&units=metric&appid=${api.key}`).then
((response) => {
console.log(response.data)
})
},[latitute, longitude])
This will call the useEffect every Time the latitude or longitude states have changed.
CodePudding user response:
Your useEffects are both running asynchronously after the first render. If you need them to be ordered, then you should run them together in the same useEffect and add your code to fetch the response within the success callback of getCurrentPosition.
See this example:
useEffect(() => {
const fetchData = async() => {
navigator.geolocation.getCurrentPosition((position) => {
setLatitude(position.coords.latitude)
setLongitude(position.coords.longitude);
const response = await axios.get(`${api.base}weatherlat=${position.coords.latitude}&lon=${position.coords.longitude}&units=metric&appid=${api.key}`);
});
});
}, []);
Note: setState is also asynchronous, hence why we use the return position directly for the axios fetch request.
An alternative to this is, as the other answer mentioned, having your second useEffect use [latitude, longitude]
in the deps array but if you don't want to constantly fetch weather API data every single time the lat/long changes, then you can just do it this way to run this once on initial component mount.