英文:
How to stop api calls on react changes
问题
I am working on a project and this is my first time working with APIs and realized that APIs are expensive, so when I make changes in my React Vite TSX project it seems to be calling it each time a change is made and it runs through my daily calls and I'm not able to experiment with it.
I tried using SWR but it was too much of a hassle and I needed to change a lot of my structure and hooks.
const LocationComponent = (props: Props) => {
const [data, setData] = useState(null);
const [weatherStatus, setWeatherStatus] = useReducer(reducer, {
weatherCode: 10001,
});
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.post(
`${postWeatherURL}?apikey=${apiKey}`,
{
location,
fields: ["temperature", "weatherCodeDay", "weatherCodeNight"],
units: "imperial",
timesteps,
startTime,
}
);
setData(
response.data.data.timelines[0].intervals[0].values.temperature
);
if (date.getHours() >= 7 && date.getHours() < 19) {
setWeatherStatus({
type: "SET_WEATHER_CODE",
payload:
response.data.data.timelines[0].intervals[0].values
.weatherCodeNight,
});
} else {
setWeatherStatus({
type: "SET_WEATHER_CODE",
payload:
response.data.data.timelines[0].intervals[0].values
.weatherCodeDay,
});
}
} catch (error) {
console.error("Error retrieving weather data:", error);
}
};
fetchData();
const interval = setInterval(fetchData, 3 * 60 * 60 * 1000);
return () => clearInterval(interval);
}, []);
const getWeatherImage = (newMapToPng: Map<number, string>) => {
let code: number = weatherStatus.weatherCode;
return newMapToPng.get(code);
}
return (
<>
<h1 id={props.weatherID} className={props.headerStyle}>
Leo's Current Weather: {data}
</h1>
<img src={`./src/assets/weatherAssets/${getWeatherImage(newMapToPng)}`} alt="Weather" />
</>
);
};
英文:
I am working on a project and this is my first time working with apis and realized that apis are expensive, so when i make changes in my react vite tsx project it seems to be calling it each time a change is made and it runs through my daily calls and im not able to experiment with it.
i tried using swr but it was too much of a hassle and i needed to change a lot of my structure and hooks.
const LocationComponent = (props: Props) => {
const [data, setData] = useState(null);
const [weatherStatus, setWeatherStatus] = useReducer(reducer, {
weatherCode: 10001,
});
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.post(
`${postWeatherURL}?apikey=${apiKey}`,
{
location,
fields: ["temperature", "weatherCodeDay", "weatherCodeNight"],
units: "imperial",
timesteps,
startTime,
}
);
setData(
response.data.data.timelines[0].intervals[0].values.temperature
);
if (date.getHours() >= 7 && date.getHours() < 19) {
setWeatherStatus({
type: "SET_WEATHER_CODE",
payload:
response.data.data.timelines[0].intervals[0].values
.weatherCodeNight,
});
} else {
setWeatherStatus({
type: "SET_WEATHER_CODE",
payload:
response.data.data.timelines[0].intervals[0].values
.weatherCodeDay,
});
}
} catch (error) {
console.error("Error retrieving weather data:", error);
}
};
fetchData();
const interval = setInterval(fetchData, 3 * 60 * 60 * 1000);
return () => clearInterval(interval);
}, []);
const getWeatherImage = (newMapToPng: Map<number,string>) =>{
let code: number = weatherStatus.weatherCode;
return newMapToPng.get(code)
}
return (
<>
<h1 id={props.weatherID} className={props.headerStyle}>
Leo's Current Weather: {data}
</h1>
<img src={`./src/assets/weatherAssets/${getWeatherImage(newMapToPng)}`} alt="Weather" />
</>
);
};```
</details>
# 答案1
**得分**: 0
我建议识别一种缓存API数据的方式,然后在您的 useEffect 中在重新发起API调用之前检查数据上次获取的时间。您可以使用本地存储来实现这一点,或者检查您已经拥有的 weatherStatus 变量。此外,您为什么要同时使用 useState 和 useReducer 呢?
<details>
<summary>英文:</summary>
I'd recommend identifying a way to cache the API data and then check when the data was last fetched before (re)making the API call in your useEffect. You could do this with local storage, or check against the weatherStatus variable you already have. Also, is there a reason to use both useState and useReducer as you have?
</details>
# 答案2
**得分**: 0
I'm assuming you're talking about fast refresh whenever you save your code in the editor.
If that's the case, every change you make is going to force a re-render, that's how it's supposed to work.
In order to prevent extra calls to the endpoints defined in your code, you have two options:
**a) Block API requests**
You can open your browser developer tools and go to the requests tab, then block the request URL you want by right-clicking on it and then selecting "Block request URL".
**b) Mock API requests**
You can use mocking libraries such as [MSW](https://mswjs.io/) to fetch from a mocked endpoint instead of the real endpoint, thus saving you API calls while developing.
<details>
<summary>英文:</summary>
I'm assuming you're talking about fast refresh whenever you save your code in the editor.
If that's the case, every change you make is going to force a re-render, that's how it's supposed to work.
In order to prevent extra calls to the endpoints defined in your code, you have two options:
**a) Block API requests**
You can open your browser developer tools and go to the requests tab, then block the request URL you want by right-clicking on it and then selecting "Block request URL".
[![block request url][1]][1]
**b) Mock API requests**
You can use mocking libraries such as [MSW](https://mswjs.io/) to fetch from a mocked endpoint instead of the real endpoint, thus saving you API calls while developing.
[1]: https://i.stack.imgur.com/8tQMa.png
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论