The title was rather vague so I will try to explain in a bit more detail here. I have a button that swaps between imperial and metric units. It changes the params in the API URL and re-renders the component that displays the weather. Now my button to swap from Day Weather to Night Weather works instantly when clicked but I am running into a weird problem where my button that swaps from metric to imperial needs to be double clicked when swapping from imperial to metric. Here's a link to the project if you want to reproduce the bug. Thank you for all the help.
http://react-weather-app-trevinshu.vercel.app/
Code for state calls:
let toggle = false;
const [displayedWeather, setDisplayedWeather] = useState(null);
const [loading, setLoading] = useState(false);
const [swapUnit, setUnits] = useState(`https://dataservice.accuweather.com/forecasts/v1/daily/5day/${key}?apikey=${apiKey}&details=true&metric=true`);
const [buttonText, setButtonText] = useState('metric');
Here's my code for the API call:
useEffect(() => {
setLoading(true);
//Fetch selected weather forecast
const displayWeather = async () => {
const data = await fetch(swapUnit);
const result = await data.json();
setDisplayedWeather(result);
};
//Timeout to delay display of weather forecast & show loading state
setTimeout(() => {
displayWeather();
toast.success(`Weather for ${city}`, { position: 'top-center', hideProgressBar: true, toastId: customId });
setLoading(false);
}, 2000);
}, [swapUnit]);
Here's my code for the button function to toggle from metric to imperial and vice versa:
//Toggle between celsius and fahrenheit
function changeParams(e) {
e.preventDefault();
toggle = !toggle;
if (toggle) {
setButtonText('Metric');
setUnits(`https://dataservice.accuweather.com/forecasts/v1/daily/5day/${key}?apikey=${apiKey}&details=true&metric=false`);
} else {
setButtonText('Imperial');
setUnits(`https://dataservice.accuweather.com/forecasts/v1/daily/5day/${key}?apikey=${apiKey}&details=true&metric=true`);
}
}
CodePudding user response:
each time any of your states change you redefine toggle to false thats how component rendering works to fix the issue you could do something like this:
function changeParams(e) {
e.preventDefault();
if (buttonText === 'Imperial') {
setButtonText('Metric');
setUnits(`https://dataservice.accuweather.com/forecasts/v1/daily/5day/${key}?apikey=${apiKey}&details=true&metric=false`);
} else {
setButtonText('Imperial');
setUnits(`https://dataservice.accuweather.com/forecasts/v1/daily/5day/${key}?apikey=${apiKey}&details=true&metric=true`);
}
}