Your first app

Starting to write our first React.js application, we learn how to structure our app and how to fetch data from an API!

Let’s use our knowledge to write an actual app! What we’ll build is a weather application that’ll display the current conditions and a 7 day forecast. Again, here is a live preview of what we’re going to build:

Prerequisites

Node.js is a JavaScript runtime for your terminal. Don’t worry too much about it, but it’s used by some tools we’ll be using to build our application. If you don’t have it installed already (check by running node -v in your terminal, which should print a version number) head over to nodejs.org, follow the instructions there to install the latest version (v6 at the time of this writing) and you’re good to go!

First steps

Facebook recently open sourced a neat little tool called create-react-app that allows us to very easily get started with our React app! It includes all the necessary build tools and transpilation steps to just get stuff done.

Let’s install it with npm:

npm install -g create-react-app

As soon as that’s finished you now have access to the create-react-app command in your terminal! Let’s create our barebones weather app:

create-react-app weather-app

The argument to create-react-app, in our case weather-app, tells the utility what to name the folder it’ll create. Since we’re creating a weather app, weather-app seems like a solid choice!

Take a look into the src/index.js file and you’ll see something like this:

Thankfully, create-react-app includes a simple server so instead of having to open the index.html file manually we can simply run npm run start in the weather-app directory and see our application at localhost:3000!

If you take a look into the src/App.js component, you’ll see a bunch of boilerplate code in there. Delete the import logo from './logo.svg'; (and the logo.svg file if you want) and all of the JSX, and instead render a heading saying “Weather”:

Save the file, go back to your browser and you should see a heading saying “Weather”! But what is all that import and export business?

Modules

Real world applications can have any number of components, ranging from a handful to thousands. Having all of them in a single file is impractical, so we structure them into modules. This allows us to keep our applications well structured and easy to work with. What we are doing above is telling the App component that we’re using the react module and the App.css module!

We can create modules by exporting something from a file, like above we’re exporting the App component. This component can then be imported in another file with import App from './path/to/App.js'. (in fact, take a look at the index.js file and you’ll see if being done!)

Node Modules

What we’ve done above when we ran the npm install command was that we installed a module. This means that somebody has pushed a module (just like our App module above!) to npm (Node Package Manager), which we can then install and use in our code!

This way we can use React and build our app without having to globally attach anything, a big benefit in terms of understanding what is going on!

Alright, back to our weather app.

We’ll need a bit of styling to make sure our app looks good. I’ve prepared that for you so you can focus on React, simply replace all the CSS in App.css with what is on this page.

We’ll also need to be able to tell our app for which location we want the weather, so let’s add a form with an input field and label that says “City, Country”!

We nest the input inside the label so the input is focussed when users click on the label!

When entering something into the input field and pressing “Enter”, the page refreshes and nothing happens. What we really want to do is fetch the data when a city and a country are input. Let’s add an onSubmit handler to the form and a fetchData function to our component!

By running evt.preventDefault() in fetchData (which is called when we press enter in the form), we tell the browser to not refresh the page and instead ignore whatever it wanted to and do what we tell it to. Right now, it logs “fetch data!” in the console over and over again whenever you submit the form. How do we get the entered city and country in that function though?

By storing the value of the text input in our local component state, we can grab it from that method. When we do that, we make our input a so-called “controlled input”.

We’ll store the currently entered location in this.state.location, and add a utility method to our component called changeLocation that is called onChange of the text input and sets the state to the current text:

Now, whichever location you enter it should log “fetch data for MyCity, MyCountry”!

Fetching data

Let’s get into fetching data. Instead of console logging a text, we need to get some weather information. We’ll be using the OpenWeatherMap API for this task, which is a free service that provides access to data for basically all locations all around the world. You’ll need to get an API key from it, so head over to openweathermap.org/api, press “Sign Up” in the top bar and register for a free account:

Now that we have access to all the weather data our heart could desire, let’s get on with our app!

Inside our fetchData function, we’ll have to make a request to the API. I like to use a npm module called xhr for this, a wrapper around the JavaScript XMLHttpRequest that makes said requests a lot easier. Run:

npm install --save xhr

to get it! While that’s installing, import it in your App component at the top:

Replace CITY,COUNTRY with a city and country combination of choice, replace YOURAPIKEY with your copied API key and open that URL in your browser. (it should look something like this: http://api.openweathermap.org/data/2.5/forecast?q=Vienna,Austria&APPID=asdf123&units=metric)

The five properties we care about are: dt_txt, the time of the weather prediction, temp, the expected temperature, temp_min and temp_max, the, respectively, minimum and maximum expected temperature, and weather[0].main, a string description of the weather at that time. OpenWeatherMap gives us a lot more data than that though, and I encourage you to snoop around a bit more and see what you could use to make the application more comprehensive!

Now that we know what we need, let’s get down to it – how do we actually fetch the data here? (by now xhr should have finished installing)

As you can see, everything we really need to take care of is constructing the url and saving the returned data somewhere!

We know that the URL has a prefix that’s always the same, http://api.openweathermap.org/data/2.5/forecast?q=, and a suffix that’s always the same, &APPID=YOURAPIKEY&units=metric. The sole thing we need to do is insert the location the user entered into the URL!

You can also change the units you get back by setting units to imperial: http://api.openweathermap.org/data/2.5/forecast?q=something&APPID=YOURAPIKEY&units=imperial

Now, if you’re thinking this through you know what might happen – the user might enter spaces in the input! URLs with spaces aren’t valid, so it wouldn’t work and everything would break! While that is true, JavaScript gives us a very handy method to escape non-URL-friendly characters. It is called encodeURIComponent(), and this is how one uses it:

Since we want React to rerender our application when we’ve loaded the data, we’ll need to save it to the state of our App component. Also, network request data is a string, so we’ll need to parse that with JSON.parse to make it an object.

Now that we’ve got the weather data for the location we want in our component state, we can use it in our render method! Remember, the data for the current weather is in the list array, sorted by time. The first element of said array is thus the current temperature, so let’s try to render that first:

Additional Material

Author

Max is the creator of react-boilerplate, one of the most popular react starter kits, the co-creator of Carte Blanche and he co-organises the React.js Vienna Meetup. He works as an Open Source Developer at Thinkmill, where he takes care of KeystoneJS.