0

I am new to reactJS, I am trying to develop a weather app using React Hooks. The useEffect hook runs infinitely, even the dependency is the same as before. So I decide to use useCallBack hook, However it shows an error.

Code as below:

import React,{useState,useEffect,useCallBack} from 'react';
import axios from 'axios';

const WeatherApp = () =>{
  const [weatherData,setWeatherData] = useState({
    latitude:1,
    longitude:0,
    city:'',
    country:'',
    description:'',
    temperature:'',
    apiKey:"96f70a610a2b066259b75fc8d23eab98",
    icon:''
  });

  const getWeatherByCoords = useCallBack(()=>{
    let api=`http://api.openweathermap.org/data/2.5/weather?lat=${weatherData.latitude}&lon=${weatherData.longitude}&appid=${weatherData.apiKey}`;

    axios.get(api)
      .then(res=>{
        const data = res.data;
        setWeatherData(pre=>({...pre,
          country:data.sys.country,
          city:data.name,
          temperature:data.main.temp,
          description:data.weather[0].description
        }));
        console.log(weatherData);

      })
      .catch(error=>errorHandler(error));
  },[weatherData]);


  const errorHandler = error=>{
    console.log(error);
  }
 useEffect(()=>{
   // const interval = setInterval(()=>{
     if(navigator.geolocation){
     navigator.geolocation.getCurrentPosition(position=>{
       setWeatherData({...weatherData,
         latitude:position.coords.latitude,
         longitude:position.coords.longitude});
       getWeatherByCoords();
     },error=>errorHandler(error),{timeout:10000});
   }
 // },1000);
   // return(()=> clearInterval(interval));
},[getWeatherByCoords]);

  // fetch(`api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${key}`)

  return(
    <div>
      <div>
        <h1>City</h1>
        <h2>Date</h2>
        <h3>Description</h3>
      </div>
      <div>
        <img alt='This is an img'></img>
        <h2>Temperature</h2>
        <p> <span>°C</span>|<span>°F</span></p>
      </div>
    </div>
  )
};

export default WeatherApp;

Error:enter image description here

If I use useMemo, the error will become: getWeatherByCoords is not a function. I am very confused. I have spend whole day on this. Thanks a lot if anyone can help.

skyboyer
  • 22,209
  • 7
  • 57
  • 64
Leo Li
  • 15
  • 5
  • 1
    typo: `useCallBack` -> `useCallback` – Hao Wu Nov 06 '20 at 06:39
  • Thank a lot. That's so a stupid mistake. It works now. The useEffect hook still runs all the time. Do you have any idea what is wrong? – Leo Li Nov 06 '20 at 06:45
  • I think you should remove the dependency `getWeatherByCoords` in `useEffect`, just leave it an empty array: `[]` – Hao Wu Nov 06 '20 at 06:48

1 Answers1

0

useEffect and useCallback will run whenever the dependency changes.

So if your dependency is the one that is going to be changed inside the hook, it will trigger a loop.

You dont' need useCallback in your case.

Just trigger axios API method inside the useEffect and then setting the state of weatherData without any dependency will do.

Kevin Moe Myint Myat
  • 1,916
  • 1
  • 10
  • 19
  • Thanks, however, if I remove the dependency the weatherDate will never be updated. It is the initial state all the time. – Leo Li Nov 06 '20 at 08:16
  • how about without the dependency array. like useEffect(() => { ...do your api calling here }); dont' console.log(weatherData); because react will prompt you to add weatherData as dependency. if you want to see if it works, just { JSON.stringify(weatherData) } in the JSX . if it's working , remove the tested string. – Kevin Moe Myint Myat Nov 06 '20 at 08:51