22
How to build a React Live Search (Rick & Morty Edition)
In this short tutorial I show you how to fetch and filter data from an API with React JS.
GitHub Repo: https://github.com/dom-the-dev/react-search-bar
I also made a step by step video
To create a new react application open your terminal and run the following command:
npx create-react-app react-live-search
This creates a complete react application. With cd spotify-react && yarn start
you jump into the projects directy and start the development server which then runs at http://localhost:3000
by default.
(If for whatever reason the port is not 3000 make sure to change the redirect url in your spotify app settings.)
Before we start to code let's remove the unnecessary stuff we don't need. So remove everythin inside of App.css
and in App.js
remove the imports as well as the html inside of the div with className App
.
So your App.js
will look similar to this:
import './App.css';
function App() {
return (
<div className="App">
</div>
);
}
export default App;
Now we are ready to implement the function to fetch Data from the Rick & Morty API.
Install axios
which will handle our HTTP request with following command
yarn add axios
and import it to the app
import axios from 'axios";
Before we fetch data, we want a state where we can save the data. For that we are going to use the useState
Hook. So let's import it and create a new state variable characters
:
Add at top of the App.js
import {useState} from 'react';
Inside of App() add:
const [query, setQuery] = useState("")
Since we want to fetch the data immediatly when we open up our app, we need the useEffect
hook. So import that as well from react.
Adjust import statement at top of the App.js and add the useEffect hook to App function.
You App.js
should now look like this:
import './App.css';
import {useEffect, useState} from 'react';
import axios from 'axios';
function App() {
const [characters, setCharacters] = useState([])
useEffect(() => {
}, [])
return (
<div className="App">
</div>
);
}
export default App;
Inside of useEffect we now want to declare the fetchData
function which performs async get Request to the API Endpoint and gets the wanted data. We wrap our code inside of a try/catch block to handle possible errors.
The fetched data will be stored in the characters state calling the setCharacters function.
const fetchData = async () => {
try {
const {data} = await axios.get(`https://rickandmortyapi.com/api/character/`)
setCharacters(data.results)
} catch (error) {
console.error(error)
}
}
And then we simply have to call this function:
fetchData()
Now we have our data stored in the state, and we are ready to dispaly it in the frontend.
For that create a new div
and inside of it we are going to map over the characters Array and dispaly the characters name as well as the image.
<div className="results">
{characters.map(character => (
<div key={character.id}>
<img src={character.image} alt={character.name}/>
{character.name}
</div
))}
</div>
If you want you can add some styling to your App.css
.
.results {
display: grid;
gap: 15px;
grid-template-columns: repeat(4, 1fr);
max-width: 1200px;
margin-left: auto;
margin-right: auto;
margin-top: 50px;
}
.search {
background-color: darkgray;
text-align: center;
padding: 15px;
}
.input {
font-size: 25px;
}
When you now visit your browser at http://localhost:3000
you should be able to see the data we just fetched. Now we are ready for the last step.
In order to filter the search results, we need to create a new state called query and set it to an empty string initially.
const [query, setQuery] = useState("")
As well as we need an input field which updates the states as soon as we start typing. For that lets create this input field and add an onChange
event which triggers the state update. The value of the input field needs to contain the query states value:
<div className="search">
<input type="text"
placeholder={"Search Character"}
className={"input"}
onChange={event => setQuery(event.target.value)}
value={query}
/>
</div>
Now we need to update our search result. To achive that we need to adjust our fetching endpoint. We need to add a "name" paramater and pass our search query into that.
Adjust this line of code:
const {data} = await axios.get(`https://rickandmortyapi.com/api/character/?name=${query}`)
Let me explain that: Initially the query variable is set to an empty string what means that we are not passing a param of name. That means we perform the regular call and get 20 first characters.
The problem now is, since we pass an empty dependancy array to the useEffect hook the fetchData
function will not be called again if we start typing our search query. To fix that we need to add query
as an dependancy to the useEffect hook. So your useEffect
will now look like this:
useEffect(() => {
const fetchData = async () => {
try {
const {data} = await axios.get(`https://rickandmortyapi.com/api/character/?name=${query}`)
setCharacters(data.results)
} catch (error) {
console.error(error)
}
}
fetchData()
}, [query])
With this changes the useEffect and also the fetchData will be called and we get new search results depending on our query state.
Visit you application at http://localhost:3000
and start typing inside your input field. The results now should update immediatly.
That's it! Thanks for reading! I would love to see a comment with any kind of feedback!
22