React API Call

Summary: in this tutorial, you will learn to call API in a React app using the built-in Fetch API provided by web browsers.

Introduction to Wikipedia Search React App

We’ll create a new React app that allows you to search Wikipedia articles. To do that, the React app needs to call Wikipedia Search API:

react api call - wikipedia search app

The React app will look like the following:

react api call - wikipedia search app prototype

We can break down this React app into the following components:

react api call - wikipedia search

Here’s the component hierarchy:

In this component hierarchy:

  • The App component is a parent component that includes other components.
  • The SearchBar component allows you to type a search term and press the Enter key to submit it.
  • The ArticleList component is responsible for rendering the search results, which are a list of articles.
  • The Article component renders each article in the search results.

Props and State Design

There are some questions we need to answer before creating the app:

  • What is the current state of the application?
  • Which component should handle the API call?
  • How should we design the props system?

The app displays a list of articles so it should have an array of articles as a state:

const [articles, setArticles] = useState([]);Code language: JavaScript (javascript)

Since the App component uses the ArticleList component to render the article list, it should pass the articles array as a prop to the ArticleList.

Additionally, the ArticleList should pass each article as a prop to the Article component for rendering each article.

If we call Wikipedia in the SearchBar component, we can get a list of articles. But how do we pass the article list from the SearchBar component to the App component?

Typically, React only allows us to pass props from parent components to the child components, not the other way around.

In other words, React does not allow you to pass a prop from a child component to its parent component.

To overcome this limitation, you can pass a function from the App component to the SearchBar component as a prop.

When the user submits the form, we can call the function to update the articles state of the App component.

react api call - states & props design

Create a new React app

First, open a terminal on your computer and create a new React app using the create-react-app command:

npx create-react-app wiki-searchCode language: JavaScript (javascript)

Next, delete all files in the src directory.

Then, create a new index.js file in the src directory and add the following code:

import ReactDOM from 'react-dom/client';
import App from './App.js';

const el = document.querySelector('#root');
const root = ReactDOM.createRoot(el);

root.render(<App />);Code language: JavaScript (javascript)

The index.js file renders the App component on the screen.

After that, create a new file named app.js in the src directory with the following code:

const App = () => {
  return <div>Wikipedia Search</div>;
};

export default App;Code language: JavaScript (javascript)

Finally, run the React app by running the following command in the terminal:

npm startCode language: JavaScript (javascript)

You’ll see the new React app on the web browser at https://localhost:3000.

Calling an API

There are several ways to call an API from a React app. The simplest way is to use the native Fetch API provided by web browsers because you don’t need to install a third-party package.

First, call the fetch() method by passing the API endpoint:

const response = await fetch(url);Code language: JavaScript (javascript)

Second, call the json() method of the Response object to parse the JSON body contents:

const results = await response.json();Code language: JavaScript (javascript)

Third, return the parsed JSON data:

return results;Code language: JavaScript (javascript)

To handle the error that may occur during the API call, you can use the try … catch statement:

try {
  const response = await fetch(url);
  const result = await response.json();
  return result;
} catch (error) {
  console.error(error);
}Code language: JavaScript (javascript)

Calling Wikipedia Search API

First, create a new file in the src directory named api.js:

Second, define a search() function that calls Wikipedia Search API for a specified search term and returns an array of articles:

export const search = async (searchTerm) => {
  try {
    const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info|extracts&inprop=url&utf8=&format=json&origin=*&srlimit=10&srsearch=${searchTerm}`;
    const response = await fetch(url);
    const results = await response.json();
    return results.query.search;
  } catch (error) {
    console.error(error);
  }
};Code language: JavaScript (javascript)

How it works.

Step 1. Define a search function that accepts a search term:

export const search = async (searchTerm) => {
   // ...
}Code language: JavaScript (javascript)

Step 2. Construct the URL API endpoint by concatenating the API URL with the search term:

const url = `https://en.wikipedia.org/w/api.php?action=query&list=search&prop=info|extracts&inprop=url&utf8=&format=json&origin=*&srlimit=10&srsearch=${searchTerm}`;Code language: JavaScript (javascript)

Step 3. Return JSON data from the API:

const response = await fetch(url);
const results = await response.json();
return results.query.search;Code language: JavaScript (javascript)

Step 4. Display an error in the catch block if it occurs:

console.error(error);Code language: JavaScript (javascript)

The search results include pageid, title, and snippet. The title and snippet may contain HTML tags.

To strip the HTML tags, we can create a new file util.js in the src directory and define the stripHTML() function as follows:

export const stripHtml = (html) => {
  let div = document.createElement('div');
  div.innerHTML = html;
  return div.textContent;
};Code language: JavaScript (javascript)

We’ll use the stripHTML in the Article component to strip HTML from the title and snippet.

Create React components

We’ll create the components for the React app.

App component

The following App component includes the SearchBar and ArticleList components:

import { useState } from 'react';
import { search } from './api';
import SearchBar from './components/SearchBar';
import ArticleList from './components/ArticleList';
import './App.css';
import logo from './wikipedia-logo.png';

const App = () => {
  const [articles, setArticles] = useState([]);

  const handleSearch = async (searchTerm) => {
    const results = await search(searchTerm);
    setArticles(results);
  };

  return (
    <>
      <header>
        <img src={logo} alt="wikipedia" />
        <h1>Wikipedia Search</h1>
        <SearchBar onSearch={handleSearch} />
      </header>
      <main id="searchResult">
        <ArticleList articles={articles} />
      </main>
    </>
  );
};

export default App;Code language: JavaScript (javascript)

How it works.

Step 1. Import the useState function from the react library because the App will hold some piece of state.

import { useState } from 'react';Code language: JavaScript (javascript)

Step 2. Import the search function from the api.js module:

import { search } from './api';Code language: JavaScript (javascript)

Step 3. Import the SearchBar and ArticleList components:

import SearchBar from './components/SearchBar';
import ArticleList from './components/ArticleList';Code language: JavaScript (javascript)

Step 4. Import the App.css and wikipedia-logo.png files:

import './App.css';
import logo from './wikipedia-logo.png';Code language: JavaScript (javascript)

Step 5. Define the App component:

const App = () => {
   // ...
};Code language: JavaScript (javascript)

Step 5. Define a piece of state (articles) which is an array of articles, and initialize its default value to an empty array:

const [articles, setArticles] = useState([]);Code language: JavaScript (javascript)

Step 6. Define a handleSearch() function that calls the search function to get the search results and update the articles state with these results:

const handleSearch = async (searchTerm) => {
    const results = await search(searchTerm);
    setArticles(results);
};Code language: JavaScript (javascript)

Step 7. Return JSX that includes a logo, a heading, a SearchBar component, and an ArticleList component.

return (
  <>
    <header>
      <img src={logo} alt="wikipedia" />
      <h1>Wikipedia Search</h1>
      <SearchBar onSearch={handleSearch} />
    </header>
    <main id="searchResult">
      <ArticleList articles={articles} />
    </main>
  </>
);Code language: JavaScript (javascript)

In the JSX:

  • Pass the handleSearch function to the onSearch prop of the SearchBar component.
  • Pass the articles state as a prop to the ArticleList component.

SearchBar component

The SearchBar component will allow users to enter a search term and run a function to call the API for searching:

import { useState } from 'react';

const SearchBar = () => {
  const [searchTerm, setSearchTerm] = useState('');

  const handleSubmit = (event) => {
    event.preventDefault();
    onSearch(searchTerm);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="search"
        name="searchTerm"
        id="searchTerm"
        placeholder="Enter a search term..."
        value={searchTerm}
        onChange={(event) => {
          setSearchTerm(event.target.value);
        }}
      />
    </form>
  );
};

export default SearchBar;
Code language: JavaScript (javascript)

How it works.

Step 1. Import the useState function from the react library:

import { useState } from 'react';Code language: JavaScript (javascript)

Step 2. Define the SearchBar component that accepts a function onSearch as a prop:

const SearchBar = ({ onSearch }) => {
   // ..
}Code language: JavaScript (javascript)

Step 3. Define a searchTerm state for the SearchBar component and initialize its default value to an empty string:

 const [searchTerm, setSearchTerm] = useState('');Code language: JavaScript (javascript)

Step 4. Create an event handler that handles the submit event:

 const handleSubmit = (e) => {
    e.preventDefault();
    onSearch(searchTerm);
  };Code language: JavaScript (javascript)

In the submit event, we call the e.preventDefault() to prevent the whole page from reloading when users submit the form and call the onSearch function with the searchTerm state as the argument.

Step 5. Return JSX that includes a form and an input element:

return (
    <form onSubmit={handleSubmit}>
      <input
        type="search"
        name="searchTerm"
        id="searchTerm"
        placeholder="Enter a search term..."
        value={searchTerm}
        onChange={(e) => {
          setSearchTerm(e.target.value);
        }}
      />
    </form>
  );Code language: JavaScript (javascript)

In the JSX:

  • Wire the handleSubmit event handler to the onSubmit prop of the form.
  • Call the setSearchTerm to update the state in the change event handler of the input element. The e.target.value returns the current value of the input element. The setSearchTerm function will assign a new input value to the searchTerm state of the component.

Step 6. Export the SearchBar component using a default export:

export default SearchBar;Code language: JavaScript (javascript)

ArticleList component

The ArticleList component displays a list of Article components:

import Article from './Article';

const ArticleList = ({ articles }) => {
  const renderedArticles = articles.map((article) => {
    return <Article key={article.pageid} article={article} />;
  });

  return <div>{renderedArticles}</div>;
};

export default ArticleList;Code language: JavaScript (javascript)

How it works.

Step 1. Import the Article component:

import Article from './Article';Code language: JavaScript (javascript)

Step 2. Define the ArticleList component that accepts an array of articles as a prop and renders each article using the Article component:

const ArticleList = ({ articles }) => {
  const renderedArticles = articles.map((article) => {
    return <Article key={article.pageid} article={article} />;
  });

  return <div>{renderedArticles}</div>;
};Code language: JavaScript (javascript)

Step 3. Export the ArticleList component as a default component:

export default ArticleList;Code language: JavaScript (javascript)

Article component

The Article component renders an article:

import { stripHtml } from '../util';

const Article = ({ article }) => {
  const url = `https://en.wikipedia.org/?curid=${article.pageid}`;
  const title = stripHtml(article.title);
  const snippet = stripHtml(article.snippet);

  return (
    <article>
      <a href={url} title={title}>
        <h2>{title}</h2>
      </a>
      <div className="summary">{snippet}...</div>
    </article>
  );
};

export default Article;Code language: JavaScript (javascript)

How it works.

Step 1. Import the stripHTML function from the util library:

import { stripHtml } from '../util';Code language: JavaScript (javascript)

Step 2. Create an Article component that renders the article prop:

const Article = ({ article }) => {
  const url = `https://en.wikipedia.org/?curid=${article.pageid}`;
  const title = stripHtml(article.title);
  const snippet = stripHtml(article.snippet);

  return (
    <article>
      <a href={url} title={title}>
        <h2>{title}</h2>
      </a>
      <div className="summary">{snippet}...</div>
    </article>
  );
};Code language: JavaScript (javascript)

In the Article component:

  • Construct a URL to an article on Wikipedia.
  • Strip HTML tags from the title and snippet of the article object.
  • Return the <article> JSX element.

Step 3. Export the Article component as a default export:

export default Article;Code language: JavaScript (javascript)

Download the Wiki Search source code.

Summary

  • Use native browser Fetch API to call an external API.
Was this tutorial helpful ?