skip to Main Content

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" />
    </>
  );
};```

2

Answers


  1. 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?

    Login or Signup to reply.
  2. 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

    b) Mock API requests

    You can use mocking libraries such as MSW to fetch from a mocked endpoint instead of the real endpoint, thus saving you API calls while developing.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search