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:
The React app will look like the following:
We can break down this React app into the following components:
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.
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-search
Code 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 start
Code 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 theonSubmit
prop of the form. - Call the
setSearchTerm
to update the state in the change event handler of the input element. Thee.target
.value returns the current value of the input element. ThesetSearchTerm
function will assign a new input value to thesearchTerm
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.