Creating a weather app with Reactjs - Part 1
Tags: react, hooks, webdev, fetch
Published: 2021-02-03 03:09:32

##Introduction
Hello! In this series, I'll show you how I went about creating a weather forecast app entirely with Reactjs. The app uses [React Hooks](https://reactjs.org/docs/hooks-intro.html), API calls from [OpenWeatherMap](https://openweathermap.org/) & [Google Geocoding Services] (https://developers.google.com/maps/documentation/geocoding/overview), and some CSS modules to make it all responsive (and look nice too, of course). Let's begin!


##Pre-requisites
* Node >= 8.10
* npm >= 5.6
* A text editor (VSCode recommended).
* Some previous knowledge of Reactjs and React Hooks.
* Some familiarity with using a command-line tool.
* Usage of git/github is optional but recommended.

## Starting out
###1. Creating the React folder
To begin, open up a new terminal and initialize a new react-app in a directory called react-weather with the create-react-app command:
```
npx create-react-app react-weather
```
This will create a template Reactjs app that we can modify to make it our own.

###2. Cleaning up our template
We won't use all files or sections of code created by the template, so let's take some time to clean up our workspace. We can go ahead and delete all of these files:
* README.md
* All files in the **/src** directory
* All files in the **/public** directory but **index.html**, **manifest.json** and robots.txt
* We can delete all the commented lines in **index.html**

###3. Create initial component
Now that our src folder is empty, nothing will be rendered to the webpage if we were to run our app. To create our first component, and see it in action, we're gonna need two files: **index.js** and **App.js**. Each one will look like this for now:

index.js
![Initial index.js code](https://dev-to-uploads.s3.amazonaws.com/i/2b11nms1znmgpfhp7rkq.png)

App.js
![Initial App.js code](https://dev-to-uploads.s3.amazonaws.com/i/3x3m43ily01t6vmw8m68.png)
Now, we can finally start creating our weather forecast app!

## Working with hooks
Since this is a weather forecast app, I'd like to give the user their initial location's forecast, and after that, they can choose to look for a different city's data. To do that, we'll use the [useEffect()](https://reactjs.org/docs/hooks-effect.html) hook, the [useState()](https://reactjs.org/docs/hooks-state.html) hook and the [getCurrentPosition()](https://developer.mozilla.org/es/docs/Web/API/Geolocation/getCurrentPosition) function from the Geolocation API.

So, when the user launches the app, we want to get their current geographical coordinates and store them in state as an object. This is what that looks like:
![Code for getting current location and sending it to the console](https://dev-to-uploads.s3.amazonaws.com/i/73lqcmqv5lj2wyka4mqj.png)

Woah! Where did all that code come from? Let me explain.

###useState()
The useState() hook sets state for a React component. It returns two values that we can get by declaring an array. First, a default value for the state variable that we want to set (an empty object in this case). Second, a function that we can call later to set the value of this state variable.

###useEffect()
useEffect() is a tricky but powerful hook. It runs after initial render and also after every update. By specifying an empty array as a second argument, we tell this hook to only run on initial render. If we populate that array with one or more state variables, the hook will run after any of those variables changes. 
So, this hook will run as the page renders, it will ask the user for permission to access their location, and will save that location data in state.

Now, as soon as the app launches, it'll ask the user for their location. If the user allows geolocation, we'll store their coordinates as an object in state. We'll handle the case in which the user blocks location in the future, for now, we'll assume that users always allow us to know their current location.

You can see that we have a button for displaying the geological information to the devtools console. Try it!