tiagofsanchez

My favorite surf spots with react-leaflet, google sheets and react-query

October 26, 2020 . 5 min read

react-leaflet

google sheets api

react-query

Table of contents

✏️edit

I always wanted to learn how to create applications that use maps and today was the day that I decided to build a small little app with a map with some of my favorite surf spots.

surf spots

If you want to check out the app click on the link.

You also can check the project repo if you would like to test the source code.

Turning google sheets into an API

First things first.

I wanted to use something very simple to store my favorite surf spots and decided to go with google sheets as I also wanted to learn how could I be using sheets as an API endpoint. It turns out that is pretty easy to do that. You would need to:

  1. Populate sheets with the information that you want to
  2. Turn your sheet public and get that link
  3. On your link get the sheet ID
  4. Use this link with your sheet ID
https://spreadsheets.google.com/feeds/list/YOUR_SHEET_ID/1/public/full?alt=json

And boom, you will now have an API that you can get your data from. Just check the API endpoint possible to use on the back of google sheets.

Let's use react-query

Or should I say, goodbye useEffect.

This simple library that enables you to fetch your data without needing useState to store your data, neither useEffect to manage the side effect of getting that data depending on the component life cycle.

You can do a lot of different things with react-query, some of them it is still way above my head, but I really liked the easy way that library works as you will need to write less code while getting a better performance. A clear win.

If you want to know more about the react-query check out the following video with Jason and Tanner.

Building a map

Ok, now we are ready to go and build our map.

The first thing that we need to do is to get our data into our component.

src/components/surfSpotMap.js

jsx
import React from "react";
import { useQuery } from "react-query";
import axios from "axios";
const url ="https://spreadsheets.google.com/feeds/list/1Dk1KD6ldix8ZEMJNa4evmrl2MJeFM5g6g9Cxis-oPjc/1/public/full?alt=json";
const fetcher = () => axios.get(url).then((res) => res.data);
const useSpots = () => {
return useQuery("spots", () => fetcher());
};
const SurfSpotMaps = () => {
const surfSpots = useSpots();
return (
<div>
MAP WILL BE HERE
</div>
)
}
return default SurfSpotMaps

Above we now have access to the our google sheet data and as a result to my favority surf spots! Nice! We now need to do a couple of different things:

  • Add a Map
  • Push data to the map

src/components/surfSpotMap.js

jsx
import React from "react";
import { Map, Marker, TileLayer } from "react-leaflet";
import { useQuery } from "react-query";
import axios from "axios";
const url ="https://spreadsheets.google.com/feeds/list/1Dk1KD6ldix8ZEMJNa4evmrl2MJeFM5g6g9Cxis-oPjc/1/public/full?alt=json";
const fetcher = () => axios.get(url).then((res) => res.data);
const useSpots = () => {
return useQuery("spots", () => fetcher());
};
const SurfSpotMaps = () => {
const surfSpots = useSpots();
return (
<div>
{surfSpots.isLoading ?
(<span>Loading...</span>)
: (
<Map center={[39.3558, -9.345]} zoom={12}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
{surfSpots.data.feed.entry.map((spot) => {
return (
<Marker
opacity={10}
key={spot.gsx$name.$t}
position={[spot.gsx$la.$t, spot.gsx$lon.$t]}
onClick={() => setActiveSpot(spot)}
></Marker>
);
})}
</Map>
)}
</div>
)
}
return default SurfSpotMaps

Here what we are doing is using <Map />, <Marker /> and <TileLayer /> to be able to render a map marking my favorite surf spots. Given that I aslo wanted to show the the name of the different spots, let's go and create that by adding the <Popup /> from the lybrary.

src/components/surfSpotMap.js

jsx
import React from "react";
import { Map, Marker, TileLayer, Popup } from "react-leaflet";
import { useQuery } from "react-query";
import axios from "axios";
const url ="https://spreadsheets.google.com/feeds/list/1Dk1KD6ldix8ZEMJNa4evmrl2MJeFM5g6g9Cxis-oPjc/1/public/full?alt=json";
const fetcher = () => axios.get(url).then((res) => res.data);
const useSpots = () => {
return useQuery("spots", () => fetcher());
};
const SurfSpotMaps = () => {
const surfSpots = useSpots();
const [activeSpot, setActiveSpot] = React.useState(null);
return (
<div>
{surfSpots.isLoading ?
(<span>Loading...</span>)
: (
<Map center={[39.3558, -9.345]} zoom={12}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
{surfSpots.data.feed.entry.map((spot) => {
return (
<Marker
opacity={10}
key={spot.gsx$name.$t}
position={[spot.gsx$la.$t, spot.gsx$lon.$t]}
onClick={() => setActiveSpot(spot)}
></Marker>
);
})}
{activeSpot && (
<Popup
position={[activeSpot.gsx$la.$t, activeSpot.gsx$lon.$t]}
onClose={() => setActiveSpot(null)}
>
<div>
<h1>{activeSpot.gsx$name.$t}</h1>
</div>
</Popup>
)}
</Map>
)}
</div>
)
}
return default SurfSpotMaps

And there you go! Now, you can check some of my favorite surf spots and the place where I came from :). If you want to check out the app click on the link.

Other stuff

Here you will also find a bunch of different resources that also could be helpful.

  • If you want to know more about maps, check out this inspiring talk by Colby.
  • To learn more about react-query check out this good tutorial from The Net Ninja.
  • In case you would like a easy way in to react-leaflet check out this video.

More posts about Code

Deploying Keystone-6 with Render

1 minutes read

Paginating through cards in NextJS not changing the url

1 minutes read

Thinking how to fetch data in nextjs

3 minutes read

Learning Advanced React with Wesbos

4 minutes read

Designing and implementing a megamenu in my digital garden

3 minutes read

All you need to know about CSS transitions

2 minutes read

Subscribe

No spam! Only good stuff!