Back
Building a Lyrics Finder App with the React Context API and TypeScript
In this article, we’ll follow a React TypeScript tutorial on building a lyrics finder app with the React Context API and React Beautiful DnD.
After multiple code updates and enhancements, including type inferences, powerful static type checking, and understandability, TypeScript has grown in popularity. In this guide, we’ll learn how to use TypeScript with the React Context API by building a React lyrics finder app from scratch.
Prerequisites
Before delving further, you should note that we will build this app with TypeScript and React.js. You don't need to know how to write advanced TypeScript; I'll guide you through each step to get you going.
To get the most out of this tutorial, you need to have a basic understanding of the following:
Basic JavaScript
ES6 JavaScript
Basic TypeScript
Basic React
Setup and Installation
Let's set up and install a React app with TypeScript. Run this command to create the project "Lyrics App":
To install TypeScript, enter the following command:
To easily create a TypeScript project with CRA, you need to add the flag --template typescript
, otherwise the app will only support JavaScript.
An easy-to-use React HTTP library called Axios makes it possible to manage and fetch data from APIs without any hassle. To install it, run:
React DnD: With the help of this simple-to-use React library, lists can easily be moved using React. This is a tool that helps develop drag-and-drop functionalities very quickly and simply.
In the root folder, run the command:
React-Dom: For routing and managing the React DOM state, let's install react-router-dom
with the command:
Let's add Bootstrap CSS after that. The best way to use React-Bootstrap is through the npm package, which you can install with npm (there’s also a yarn package if you prefer).
After installation is complete, your package.json should look like this:
We’re done with our setup! Let’s start writing some code.
Create Your API Token
Before we get into building, we need an API token to run and fetch music lyrics. For this tutorial, we will use the Musixmatch API token. Create a new account on Musixmatch for a unique token.
Open an account and navigate to the Dashboard.
Click the Applications button and scroll down.
Your Applications dashboard contains your API token and your username.
Copy the API token and include it in a .env
file in the root folder as so:
Fetching Lyrics Data from the React Context API
In React v16, the React Context API was added as a mechanism to communicate data among components without passing props down at each level.
It's good practice to have distinct type definition files because it strengthens the project's structure. The stated types can either be utilized explicitly by importing them into another file or by reference without importing them (though they have to be exported first).
Now that this is established, we can get our hands dirty and write some useful code.
As you can see from the code written above, the ContextPro
interface defines the types which expect an array or null object value or string type for track_list
and heading
.
While fetching React Context API data, observe the URL link before the main API data “https://cors-anywhere.herokuapp.com”. This link enables us to access the API data. The API data returns an error due to CORs restrictions. Hence, the CORs link above accounts for the error and grants access to the API.
When creating the context, we set the default state value to null or an empty array temporarily; the intended values will be assigned by the provider. Here, I initialized the state with some data to have lyrics.tsx
work.
Only the components that require the data will receive it thanks to the context. Next, we import the context into App.js and wrap the context around the parent-level component. Here is how the App component looks:
The values are then passed to the context so that the components can consume them as above.
Create the Components and Consume the Context API
We’ll build a <Search>
component that lets a user input a song title and <LyricLists>
and <Lyrics>
components to display the lyrics search results in a mapped and ordered pattern.
Finally, a <Lyric>
component displays the actual lyrics when clicked.
Let's begin by making a new folder in the src directory named “Components” because that's where all of our components will be. Let's now develop the components for <Lyrics>
, <LyricLists>
and <Search>
. They must then be imported into our App.js code.
Using the useState
hook, the <Search>
component below lets us manage user-entered data. Once we get the form data, we utilize the context object's setState function to show it on the lyricLists
component.
First, we’ll create a function that makes an API call to Musixmatch using the Axios library:
Note that I use typecasting on the useContext
hook to prevent TypeScript from throwing errors because the context will be null or an empty array at the beginning.
Then, to confirm that we are receiving results from the API, we perform an API request on Axios using the GET method. We then use the then-catch block to obtain the API response that follows. In addition, we take advantage of the React Typescript useState
hook.
We now need to show the data to the user in our app after successfully obtaining it from the API. We'll create a very basic search field where a user may enter the title of their favorite song lyrics.
We'll ask the Musixmatch API for the lyrics information and show the result in our user interface.
In the return
section, we have a search input that accepts a name and listens for an event to perform a search or call the API.
As you can see above, we have a presentational component that shows a map listing of lyrics. It receives the state value from the context alongside track_list
and heading
from a destructured state object and the function to update it as parameters that need to match the Props type defined in the context.
We also imported some methods from React Beautiful DnD to handle the droppable content area.
DragDropContext
is going to give our app the ability to use the library. It works similarly to the React Context API; notice how the entire <lyriclists>
component is wrapped around the dragdropcontext
.
With the aid of the ref, Droppable
gives you the ability to drop an item into a list where its properties are inherited.
After destructuring the track from <Lyrics>
components, import and wrap <LyricLists>
with a draggable method. By clicking and dragging the draggable object with the mouse, you can move it around the viewport.
Next, we create a <Lyric>
component to display individual lyric data as well as artist name
and track_id
. This component contains a unique link id which was created using the useParams()
hook and can only be accessed from inside <LyricLists>
components.
Notice how we applied the useEffect
hook, which allows us to interact with the environment without affecting the rendering of the component.
useParams
returns an object of key/value pairs of URL parameters. This gives a unique key to the route access. Hence, using params.id
as a dependency for the useEffect
hook enables the Axios API call to only run when we click on “view lyrics.”
Then we have the return div
, which displays details of the music data like name, year, artist, release date, etc. You can display as many details as you want.
Conclusion
Awesome! Our app now does all tasks. Here is a summary of what we did:
We received an API key for the Musixmatch API. We also created a component that enables title-based lyrics searches and stores the results in the component's state.
The function was then sent to the search form so that it would take effect when we clicked the button or pressed enter. After that, we created a lyric component that shows the response information we had obtained from the React Context API and put the response in a single lyric state that can be accessed using the useparam
hook.
The repository for the component library developed in this article can be found on my GitHub.