How to build a React Live Search (Rick & Morty Edition)
Tags: react, tutorial
Published: 2022-01-03 10:03:53

---
title: How to build a React Live Search (Rick & Morty Edition)
published: true
description: Create a live search with data from an API
tags: react, tutorial
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d9ib96qv7ipjzbe5dudy.jpg
---

In this short tutorial I show you how to fetch and filter data from an API with React JS.

If you have any questions [hit me up von Twitter](https://twitter.com/Dom_TheDev)

GitHub Repo: https://github.com/dom-the-dev/react-search-bar

> [Subscribe to my YouTube Channel](https://www.youtube.com/channel/UCAa2t4QIxlaUuPO2FKq5TDw?sub_confirmation=1)

I also made a step by step [video](#video)

#### List of contents
- [Create React App](#create-react)
- [Clean Up](#clean)
- [Fetching Data](#fetch-data)
- [Display Data](#display-data)
- [Filter Search Results](#filter-search)

### Create React App <a name="setup-react"></a>

To create a new react application open your terminal and run the following command:

```CLI 
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.)

### Clean Up <a name="clean"></a>

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: 


```react
import './App.css';

function App() {

    return (
        <div className="App">

        </div>
    );
}

export default App;

```

### Fetch Data <a name="fetch-data"></a>

Now we are ready to implement the function to fetch Data from the Rick & Morty API.

> https://rickandmortyapi.com/

Install `axios` which will handle our HTTP request with following command

```cli
yarn add axios
```

and import it to the app

```react
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:

```react
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.

```react
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()`


### Display Data <a name="display-data"></a>

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.

```react
<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`.

```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.

### Filter Search Results <a name="filter-search"></a>

#### Add search input
In order to filter the search results, we need to create a new state called query and set it to an empty string initially.

```react
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:

```react
<div className="search">
    <input  type="text"
            placeholder={"Search Character"}
            className={"input"}
            onChange={event => setQuery(event.target.value)}
            value={query}
    />
</div>
```

#### Update search results

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:
```react
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:


```react
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!

### Step by Step Video <a name="video"></a>

{% youtube Rm5b7PgcGqQ %}