0

I'm trying to create a customised homepage for my browser. I have implemented an API to show the weather, but only works when I press enter. I want to display the data automatically when loads the page, without pressing enter, showing the Bristol weather automatically and when I type another location the api will be able to request and render. I tried a lot of ways like (removing the hook, changing the initial state of the hook but nothing seems to work)This is my code:

    const [query, setQuery] = useState('Bristol');
    const [weather, setWeather] = useState({});

const search = async () => {
    fetch(`${api.base}weather?q=${query}&units=metric&APPID=${api.key}`)
    .then(res => res.json())
    .then(result => {
        setWeather(result);
        setQuery('')
        console.log(result)
    });
}
    return(
        <div className="app">
            <main>
                <div className="search-box">
                    <input
                        type="text"
                        className="search-bar"
                        placeholder="Search..."
                        onChange={e => setQuery(e.target.value)}
                        value={query}
                        onKeyPress={search}
                    />
                </div>
                {(typeof weather.main != "undefined") ? (
                    <div>
                    <div className="location-box">
                        <div className="location">{weather.name}</div>
                        <div className="date">{dateBuilder(new Date())}</div>
                    </div>
                        <div className="weather-box">
                            <div className="temp">
                                {Math.round(weather.main.temp)}
                            </div>
                            <div className="weather">
                                {weather.weather[0].main}
                            </div>
                        </div>
                    </div>
                ) : ('')}
            </main>
        </div>
    )
} 

I'm new to ReactJS and it's a bit confusing, because here I use the same file to code and to render, I did this before but I was using plain JavaScript with express, etc.. and I rendered into an HTML.

Gabriel Savian
  • 166
  • 1
  • 11
  • you might be needed to revise ReactJS hooks https://reactjs.org/docs/hooks-overview.html. – Md. Abu Sayed Dec 23 '20 at 13:11
  • Does this answer your question? [How to call loading function with React useEffect only once](https://stackoverflow.com/questions/53120972/how-to-call-loading-function-with-react-useeffect-only-once) – Nisharg Shah Dec 23 '20 at 13:13
  • @NishargShah Almost there, It loads, but in less than 1 second clears automatically. – Gabriel Savian Dec 23 '20 at 13:18

2 Answers2

1
useEffect( () => search(), [])  
T.arar
  • 111
  • 4
  • 1
    I guess the approach in my answer is more idiomatic as it will automatically re-execute the search when the query changes. Also it eliminates the imperative `onKeyPress={search}` event handler – ingmak Dec 23 '20 at 13:23
  • you can use useEffect and pass the search query to the dependecies table, so every time the variable changes it will make a re_render with the new result. – T.arar Dec 24 '20 at 11:51
1

Try wrapping the fetch call in useEffect:

  useEffect(() => {
    fetch(`${api.base}weather?q=${query}&units=metric&APPID=${api.key}`)
      .then((res) => res.json())
      .then((result) => {
        setWeather(result);
        console.log(result);
      });
  }, [query]);

The second argument is a so called dependency array. Whenever its contents change the effect will be rerun, see https://reactjs.org/docs/hooks-effect.html.

Also remove onKeyPress={search} as it is redundant with onChange={e => setQuery(e.target.value)}

Further resources:

ingmak
  • 119
  • 1
  • 11