How to create a simple search app in React

gideon bamuleseyo
Developer Circle Kampala
7 min readFeb 5, 2019
IMAGE CREDIT: Laura Gift

Hello there, welcome to my second blog post on React. In my first blog post, I introduced you to React. Today we are going to dive a little bit deeper into React as we create a simple search application.

Below is a look at the finished application

gif of the finished app

We are going to create a simple application that grabs a search value from the user then makes an API call to one of the themealdb.com APIs, then displays the results. Below is the URL we shall use to make the query.

https://www.themealdb.com/api/json/v1/1/search.php?s=Arrabiata

Let's get started by creating a new React project using create-react-app. We shall call our project meal-search. Navigate to where you want to create your project, then run the command below in your terminal.

create-react-app meal-search

This will give you a fresh clean react project. cd into meal-search. or whatever name you gave your project. You should have a file structure similar to the one below

Exploring the files and folders.

  1. node_modules. This folder contains the javascript packages (directories) that our app is using. When you install node packages. The directories of these packages get placed in this folder
  2. public. This folder contains files that are accessible to the public, this is the folder the server looks into when displaying web pages of our app.
  3. favicon.ico. Favicon is a website icon that appears on the left-hand side of the tab in which a web page is open just next to the title of the website.
  4. index.html. This is the homepage (default page) of the application. All our react components will be rendered through this page.
  5. manifest.json this file just contains some information about our react app.
  6. src. This folder will contain all of the source code that we are going to write.
  7. App.css. This file contains CSS for the App.js component.
  8. App.js. This file is a basic component that renders what we currently see when we run our app.
  9. App.test.js. This file contains tests for the basic App.js component.
  10. index.js. This javascript file is the entry to our application. This is the file where we plug our components that plug it into the root divin the index.html
  11. logo.svg. This is the React logo that gets displayed when we run our application.
  12. serviceWorker.js. This is a file that is automatically generated by the create-react-app. This file basically serves assets from the local cache when in a production environment.
  13. .gitingnore. create-react-app automatically initializes our app to be tracked by git and also generates this .gitignore file. Just as the name sounds this file is used to ignore files and folders you don't want Git to track.
  14. package.json. This file contains some metadata about our application. Most importantly it contains a list of dependencies with their versions that our application is using. It would the equivalent of the requirements.txt file in python.
  15. README.md. This is a file that is displayed on the GitHub repository of your application. Just as the name sounds, this file should contain information that people visiting your application’s repository can read to inform them about your application.
  16. yarn.lock This file contains more metadata about the javascript packages and their versions that your app is using.

Running the app

You can run the app by running npm start command in your terminal. This will automatically open up your default browser with the app running on localhost on port 3000.

Editing project files and creating our app

We are going to delete a few files we will not be needing. Delete App.js, App.css, App.test.js, and serviceWorker.js.

In the src/index.js file, we also delete some lines of code. We will start with imports from files we have deleted.

import App from ‘./App’;import * as serviceWorker from ‘./serviceWorker’;

Let us also delete their instances in the file

// If you want your app to work offline and load faster, you can change// unregister() to register() below. Note this comes with some pitfalls.// Learn more about service workers: http://bit.ly/CRA-PWAserviceWorker.unregister();

Let us now create our search component, In the src folder, create a new file and call it Search.js Add the code below to this file

import React, { Component } from "react";class Search extends Component {state = {};render() {return <h1>Welcome to the meal search app</h1>;}}export default Search;

In the src folder, in the index file, import this new component we have just created. import Search from ‘./Search’;

Replace this line

ReactDOM.render(<App />, document.getElementById('root'));

with

ReactDOM.render(<Search />, document.getElementById('root'));

This will render the Search component that we have just created. When you go to your browser, the application will reload displaying the search component

Now, let us add a search input and a button to perform the search. In your Search.js file, in the render method, replace the return statement with the one below

return (<div><h1>Welcome to the meal search app</h1><input name="text" type="text" placeholder="Search" /><button>Search</button></div>);

We now have a skeleton of what we can use to perform the search, let us style it a little bit before we go ahead. In the src folder, create a CSS file, you can call it anything, I will call mine Search.css Add the code below to your CSS file

* {margin: 0;padding: 0;}h1 {color: #4286f4;margin-top: 30px;margin-bottom: 60px;}div {text-align: center;width: 80%;margin: 0 auto;}input {width: 100%;margin: 10px;padding: 18px 10px;border-radius: 4px;border: 1px solid #4e5766;box-shadow: 1px 0.5px #888888;font-size: 18px;}button {padding: 12px 10px;width: 30%;border-radius: 4px;background-color: #4286f4;color: #ffffff;cursor: pointer;font-size: 18px;}

This will style our skeleton and this is what it will look like

Alright, now that we have the interface that can allow us to perform a search, let us power it up. First, we need a variable that will hold the search value entered by the user. In state, create this variable, I will call mine searchValue

state = {searchValue: '',};

Alright, now let us set the input to this value, by adding the value attribute. While at this, let us also add an onChange listener to our input element.

<inputname="text"type="text"placeholder="Search"onChange={event => this.handleOnChange(event)}value={this.state.searchValue}/>

We have set the onChange to be handled by a function handleOnChange which takes in event as a parameter. Event is an object of that is created when the user types something in the input element.

Now let us create the handleOnChange function. In this function, we basically want to grab the value the user typed then use it to perform the search. In your Search class, just below state, add the code below to create the function.

handleOnChange = event => {this.setState({ searchValue: event.target.value });};

Now, that we have the search value let us perform the search. To do this we need to first add an onClick attribute to our Search Button.

<button onClick={this.handleSearch}>Search</button>

We have added an onClick attribute that listens out for a click on this button. We have set this attribute to a function handleSearch . Let us define this function now, below the handleOnChange function, add this code.

handleSearch = () => {}

Alright, now that we have a function to handle the search, let us make that API call. I am going to use the Fetch API for this. Below the handleSearch function, create a new function to make the API call.

makeApiCall = searchInput => {var searchUrl = `https://www.themealdb.com/api/json/v1/1/search.php?s=${searchInput}`;fetch(searchUrl).then(response => {return response.json();}).then(jsonData => {console.log(jsonData.meals);});};

Call this function in the handleSearch function with the searchValue.

handleSearch = () => {this.makeApiCall(this.state.searchValue);};

We are now able to fetch the meals that contain the letters the user entered in the search field. Let us display these results. First, we need a variable to hold the meals being returned, preferably an array. So, in state, create a variable called meal and set it equal to an empty array.

state = {searchValue: "",meals: []};

Now back in our makeApiCall function, let’s set this array to the meals array being returned. So in the last .then, add this line

this.setState({ meals: jsonData.meals });

Now that we have this array in our state, let us render it. Below the button element in the render function, add this code.

{this.state.meals ? (<div>{this.state.meals.map((meal, index) => (<div key={index}><h1>{meal.strMeal}</h1><img src={meal.strMealThumb} alt="meal-thumbnail" /></div>))}</div>) : (<p>Try searching for a meal</p>)}

You should now be able to perform the search and display the results.

Voilà, there we have it, a simple search app. I am just going to style this a little bit more. You can find the final code on Github here.

Alright, thank you so much for reading, click on those clap hands if you found this helpful or leave a comment if you have any feedback for me thank you.

--

--

gideon bamuleseyo
Developer Circle Kampala

software developer, thought leader, growth and change advocate