Introduction
Managing the state of a React application using class components can become a really daunting task. In versions of React earlier than React v16, you had to convert your functional components into class components whenever you wanted to use state. All that changed with the introduction of React Hooks. I recently started using React Hooks for managing state and I have to say, my code has become much simpler and cleaner.
I used the React Hooks course by Codevolution on YouTube to get an introduction into the world of React Hooks. From the course, I was able to easily understand the two most important hooks in React, which are:
- the useState hook, which allows us to use state within functional components
- the useEffect hook, which allows us to perform side effects in functional components
Working on a project
I stopped the course after learning how to use the useEffect hook, and wanted to put what I had learned into practice by working on a project. I visited the Frontendmentor website and picked the IP Address Tracker challenge to test my newly gained superpower.
Default view of the IP address tracker app in Google Chrome. Changes depending on the client request's public IP address
APIs/Libraries used
The challenge involved the use of two APIs namely:
- IP Geolocation API by IPify to get the IP address locations
- LeafletJS to generate the map shown
For styling the app, I used SCSS, which I also learned after finishing the hooks tutorial.
For making GET requests to the APIs, I used the promise-based HTTP client, Axios.
For rendering the map using React Components only, I used React Leaflet.
How it works
When the page loads initially, the useEffect hook runs a function that does the following:
- fetches the location details from the Geolocation API using Axios. The IP address used for fetching defaults to the client request's public IP address
- stores the location details in the state using the useState hook
However, the useEffect hook runs this function only once after the App component mounts, similar to the componentDidMount lifecycle method in class components.
Next, React Leaflet renders the map shown. Then, the Leaflet API generates the location pointer using the coordinates gotten from the location details.
When a user enters and submits an IP address, the function from the first paragraph above runs again, this time with the IP address entered by the user. This triggers a re-render of the app as the state gets updated with the new location details.
Below is a short video demo which shows how the app works in Google Chrome:
Challenges faced
I had no issues while using React Hooks and SCSS. But, working with React Leaflet proved a bit challenging. The design for the challenge made use of a custom location marker icon rather than the default icon provided by Leaflet. I tried importing the custom icon then passing it as a prop in the Marker
component(which allows customization of the location marker icon) provided by React Leaflet but to no avail.
Luckily, I was able to find a solution to this on Stack Overflow. The correct steps to follow to add a custom icon to the map include:
- creating a new icon component using the Leaflet library. This allows you to set parameters such as your custom icon image URL, icon size, etc
- passing the newly created icon component as a prop to the
Marker
component
Conclusion
This project was done so I could practice React Hooks, SCSS, and Axios. Working with React Hooks on this project was really fun and I look forward to learning and using more hooks in React.
The flexibility and the DRY approach SCSS gave me was also splendid and I will definitely be using it more in my projects.
I was not able to explore the full features of Axios since I only made a GET request with it, but, working with it does seem worth it. I will most definitely use it in other situations as time goes on to get a good grasp of it.
You can test out the live version of the IP Address Tracker app here. If you're also interested in the source code, you can find it on GitHub.