Intro to Web Mapping with React.js

John Lister
9 min readApr 16, 2023

--

Quick and easy guides for building Web Map components in React.js

No beating around the bush — this is a scatter blast series of tutorials showing you how to leverage React.js to build simple Web Map components (think speed dating but with JS Mapping Libraries). We are using some of the more popular Web Mapping Javascript libraries; Mapbox, Leaflet, OpenLayers, ArcGIS and Carto. Nothing fancy here, we are just going to build a simple component for each that renders a map and shows some data. My hope here is to get you hands on with React.js and show you how easy it is to get started. Most importantly I want to get you MAPPING.

Map Component Tutorials

Though I encourage you to follow this introduction in it’s entirety, please feel free to use these links to navigate to each of the individual Mapping Library tutorials (some may still be in the works but I’ll update this article and the sourcecode as I complete each section). You are not required to follow in any particular order nor are you required to complete them all — you can simply just take what you need!

  • Part 1— Mapbox
  • Part 2— Leaflet
  • Part 3—ArcGIS Coming Soon
  • Part 4— Carto Coming Soon
  • Part 5— OpenLayers Coming Soon
  • Mayyybe Part 6 ?— Google Maps let me know in the comments if you want Google Maps added!

1. The Pre-Reqs

I welcome all skill levels willing to embark on their own Web Mapping journey to follow along!

If you haven’t already, you’ll need to install Node.js I recommend installing their latest stable version. You can validate if you have Node installed by typing node -v in your terminal:

I am using an ancient version of node so don’t follow me off the cliff! 14 has just been my old faithful :)

2. Getting Started with React.js

To get started with react we’ll install the create-react-app boilerplate globally on our machine — we need this to build our react application

npm install -g create-react-app

This Starter Github Repo has all the code we’ll build in this first part BUT following along may help you understand the design considerations and learn a bit of React.js in the process. We’ll add our Map Components 1 by 1 to this source code in each of the linked tutorials — so if you don’t care about how we built the basic React application simply clone the repo, use npm i to install all necessary packages and move on the the next part!

NOTE the Tab Functionality in this part is based on this article by Chinedu Imoh.

Our react application is super simple, it allows us to tab through each of the Map Components we’ll code throughout tutorial series — clicking a tab renders a new Map component, but for now it’s just place holder text that loads:

Our Application from Starter Repo

To get started let’s create our react application using our terminal — open VSCode and start a terminal in the directory you want to build your application.

Run create-react-app react-map-tutorial in the terminal to create our React Application (It may take a few minutes)

We’ll now see a folder containing our application code — let’s cd into our application cd react-map-tutorial

VSCode File Explorer showing react app and us using cd to run the terminal in it

We can run our application using npm start and by default a browser should open but if not simply navigate to the Local: url output in the terminal to view your application:

Our terminal should show this if our application started successfully

Navigating to the Localhost url — we should see something similar to this in our browser, this is our React app in it’s current state:

Basic react app

All the code we’ll care about for this will live in the react-map-tutorial/src directory. Let’s discuss a few of the files in our application:

  • index.js is just like an index.html file if we run our app it always points to it’s index file unless we configure it not to. We aren’t going to do anything with the index file for this tutorial but, if we look at it, we can see it is responsible for rendering our main component (app.js).
  • app.js is our main application component — it’s basically a container that will hold all our components and where/how we render them.
  • app.css this is our main components styling file it can also be used as the parent styling file for components we’ll render in our app.js.

3. Getting hands on with our React App

Replace all the code in our app.css with this:

* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
/* main component styling */
.App {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
/* Tab component css*/
.Tabs{
width: 80%;
height: auto;
min-height: 80%;
background: #ffffff;
border: 1px solid #6bb7d8;
margin: 3.5rem auto 1.5rem;
padding: 2rem 1rem;
color: #003a53;
border-radius: 2rem;
@media (max-width: 769px) {
padding: 2rem 0;
}
}

/* Tab Navigation */
ul.nav {
width: 60%;
margin: 0 auto 2rem;
display: flex;
align-items: center;
justify-content: space-between;
border: 1px solid #6bb7d8;
border-radius: 2rem;
padding-left: 0px;
@media (max-width: 768px) {
width: 90%;
}
}
ul.nav li {
width: 50%;
padding: 1rem;
list-style: none;
text-align: center;
cursor: pointer;
transition: all 0.7s;
}
ul.nav li:first-child {
border-bottom-left-radius: 2rem;
border-top-left-radius: 2rem;
}
ul.nav li:last-child {
border-bottom-right-radius: 2rem;
border-top-right-radius: 2rem;
}
ul.nav li:hover {
background: #6bb7d8;
}
ul.nav li.active {
background: #6bb7d8;
}

/* Tab Content Styles */
.TabContent {
font-size: 2rem;
text-align: center;
}

Replace all the code in ourapp.js with this

import "./App.css";
const App = ()=> {
return (
<div className="App">

</div>
);
}
export default App;

Our main component is a function calledAppthat returns html content that will contain our Map Components. We export this Appfunction so we can import it in index.js and our application knows how to render it — MAGIC!

Create a folder in react-map-tutorial/src called “Components” in that new directory make 2 sub directories called “MapComponents”, “TabComponent

Newly created directories

In our now react-map-tutorial/src/TabComponent we are going to write code that renders our tabs and adds functionality they need to render a component. create a file called Tabs.js — this is our component that will display our tab “buttons” — in Tabs.js add the following

import React, { useState } from "react";

const Tabs = () => {
const [activeTab, setActiveTab] = useState("map1");

return (
<div className="Tabs">
<ul className="nav">
<li className={activeTab === "map1" ? "active" : ""}>Map 1</li>
<li className={activeTab === "map2" ? "active" : ""}>Map 2</li>
</ul>

<div className="outlet">
{/* Map Components will go here */}
</div>
</div>
);
};

export default Tabs;

Okay so we have our Tabs component function that is returning our Tabs html with the Tab Links under the <ul> tag and then where we intend to render our Map Components under our outlet <div> tag

You’ll notice we have some fancy expressions {activeTab === "map1" ? "active" : ""} in our Tab LinksclassName

<li className={activeTab === "map1" ? "active" : ""}>Map 1</li>
<li className={activeTab === "map2" ? "active" : ""}>Map 2</li>

We are using the react lifestyle hook called useState where we add activeTab and setActiveTab properties to our Tab component.

You can see that I just tell our component that I want to set this state on “map1” by default which will make the condition true and set the className to be “active” for “map 1” (REMEMBER in our app.css we have a style rule for this active class which will highlight the link ul.nav li.active) — In just a moment we’ll add functionality that will set the state on the Tab Links per user interaction.

You can see we are exporting out with export default Tabs; we’ll import this component to our App.js component to display it in our application

Go ahead and update our App.js to have our Tabs component imported and add our imported component in the code that is returned — You see how easy this is? Now the Tab component we made just fits right into our Main App component - it’s magic!

import "./App.css";
import Tabs from "./Components/TabComponent/Tabs";
const App = () => {
return (
<div className="App">
<Tabs />
</div>
);
}
export default App;

Our application will now look like this — note the Map 1 Tab highlighted

Create 2 new JavaScript files in react-map-tutorial/src/TabComponent

TabNavItem.js this component will be used to represent a Tab Link navigation item — we’ll dynamically set the active className using the activeTab property and then set a new active tab with the setActiveTab property

/*
NOTE the Tab Functionality in this part is taken from this article
by Chinedu Imoh https://blog.logrocket.com/how-to-build-tab-component-react/
*/

import React from "react";
const TabNavItem = ({ id, title, activeTab, setActiveTab }) => {

const handleClick = () => {
setActiveTab(id);
};

return (
<li onClick={handleClick} className={activeTab === id ? "active" : ""}>
{ title }
</li>
);
};
export default TabNavItem;

TabContent.js this component is used to dynamically render the Map Component content inside our Tabs component using the idand activeTab property — the { children } syntax renders ensures all the child components are referenced

/*
NOTE the Tab Functionality in this part is taken from this article
by Chinedu Imoh https://blog.logrocket.com/how-to-build-tab-component-react/
*/

import React from "react";

const TabContent = ({id, activeTab, children}) => {
return (
activeTab === id ? <div className="TabContent">
{ children }
</div>
: null
);
};

export default TabContent;

Now lets go back to Tabs.js and do a big overhaul — we are going to import our new TabComponentand TabNavItem components. Using this new functionality we'll add a TabNavItem component (to navigate) and a TabContent Component (with some place holder text) for each Map Component we plan on building in the rest of this tutorial series:

import React, { useState } from "react";
import TabNavItem from "./TabNavItem.js";
import TabContent from "./TabContent.js";

const Tabs = () => {
const [activeTab, setActiveTab] = useState("mapbox");

return (
<div className="Tabs">
<ul className="nav">
<TabNavItem title="Mapbox" id="mapbox" activeTab={activeTab} setActiveTab={setActiveTab}/>
<TabNavItem title="Leaflet" id="leaflet" activeTab={activeTab} setActiveTab={setActiveTab}/>
<TabNavItem title="OpenLayers" id="openlayers" activeTab={activeTab} setActiveTab={setActiveTab}/>
<TabNavItem title="ArcGIS" id="arcgis" activeTab={activeTab} setActiveTab={setActiveTab}/>
<TabNavItem title="Carto" id="carto" activeTab={activeTab} setActiveTab={setActiveTab}/>
</ul>

<div className="outlet">
<TabContent id="mapbox" activeTab={activeTab}>
<p>Mapbox works!</p>
</TabContent>
<TabContent id="leaflet" activeTab={activeTab}>
<p>Leaflet works!</p>
</TabContent>
<TabContent id="openlayers" activeTab={activeTab}>
<p>OpenLayers works!</p>
</TabContent>
<TabContent id="arcgis" activeTab={activeTab}>
<p>ArcGIS works!</p>
</TabContent>
<TabContent id="carto" activeTab={activeTab}>
<p>Carto works!</p>
</TabContent>
</div>
</div>
);
};

export default Tabs;

Our application should now look like this:

Clicking each individual TabNavItem should change the rendered TabContentText

4. To Conclude

I know we didn’t create any maps in this intro but I trust you see how easy it is to get started with React.js— there’s a reason it has become the go to Frontend JavaScript Framework for Developers and I hope you consider it as your FE JavaScript Framework for your next Web Mapping project.

I hope you found this tutorial helpful at getting hands on with React.js and I trust you’ll find individual tutorials for each JavaScript mapping Library Useful too. Choosing a JavaScript Web Mapping library can be difficult and depends on numerous different factors — at the surface these libraries all basically do the same thing but as you peel back the layers of each you find they each have their own strengths and weaknesses. It’s a good idea to research them thoroughly and find the one that works for you and your business needs. If you need some help deciding on a JS Web Mapping libraries to use, feel free to reach out and I’ll be happy to offer assistance where ever possible.

5. The Sourcecode

What kind of monster would I be if I didn’t include the source code? Here are 2 Github Repo’s:

Credit where it’s due:

Special thank you to Chinedu Imoh for his work on his How to build a tab component in React article which served as the foundation for this tutorial.

--

--

John Lister

GeoScrub Founder https://www.geoscrub.org/ . Software Engineer with a GIS Background. Passionate about mapping & sustainability!