Building a React Country Search Component with Asynchronous Data Fetching
I will show you how to build a real-world small project.
Introduction
I came across a small task on Upwork and decided that those types of tasks a Front-end developer would have almost at every project.

In this article, I'll guide you through building a React Country Search component that asynchronously fetches country data from the REST Countries API. The component will include features such as real-time search with the debouncing mechanism.
Setting Up the React App
Assuming you have a React app already set up, you can create a new component for the Country Search. Let's name it CountrySearch.js.
Creating the CountryInput Component
Here's the initial structure of the CountryInput component:
1import { useEffect, useState } from 'react';
2import styles from './Input.module.css';
3import CountriesOptions from './CountriesOptions';
4
5const CountryInput = ({ value, setValue }) => {
6 const [inputValue, setInputValue] = useState(value?.name?.common);
7
8 const [isActive, setIsActive] = useState(false);
9 const [isLoading, setIsLoading] = useState(false); // status of data loading
10 const [options, setOptions] = useState([]); // list of countries by provided name (inputValue)
11
12 const handleInputChange = (e) => {
13 setInputValue(e.target.value);
14 };
15
16 const resetAutocomplete = (val) => {
17 setInputValue(val.name.common);
18 setIsActive(false);
19 setOptions([]);
20 };
21
22 const handleSelectCountry = (value) => {
23 setValue(value);
24 resetAutocomplete(value);
25 };
26
27 useEffect(() => {
28 const getCountries = async () => {
29 setIsLoading(true);
30 try {
31 const response = await fetch(
32 `https://restcountries.com/v3.1/name/${inputValue}`
33 );
34 if (response.ok) {
35 const newOptions = await response.json();
36 setOptions([...newOptions]);
37 }
38 } catch (err) {
39 console.log('Something is incorrect');
40 setOptions([]);
41 } finally {
42 setIsLoading(false);
43 }
44 };
45
46 const debounceTimer = setTimeout(() => {
47 if (inputValue) {
48 getCountries();
49 }
50 }, 500);
51
52 return () => clearTimeout(debounceTimer);
53 }, [inputValue]);
54
55 return (
56 <div className={styles.autoselect}>
57 <input
58 placeholder='Search for a country...'
59 type='text'
60 value={inputValue}
61 onClick={() => setIsActive(true)}
62 onChange={handleInputChange}
63 />
64 {isActive && (
65 <CountriesOptions
66 list={options}
67 onClick={handleSelectCountry}
68 isLoading={isLoading}
69 />
70 )}
71 </div>
72 );
73};
74
75export default CountryInput;
Countries options
1import Loading from './Loading';
2import styles from './CountriesOptions.module.css';
3
4const CountriesOptions = ({ list, onClick, isLoading }) => {
5 return (
6 <div className={styles.popup}>
7 {isLoading && <Loading />}
8 {!list.length && !isLoading && 'No available options'}
9
10 {list.length > 0 && !isLoading && (
11 <ul className={styles.list}>
12 {list.map((country) => (
13 <li
14 key={country.name.common}
15 className={styles.listItem}
16 onClick={() => onClick(country)}>
17 {country.name.common}
18 </li>
19 ))}
20 </ul>
21 )}
22 </div>
23 );
24};
25
26export default CountriesOptions;
Integrating the Component
To use this component in your application, import it where needed and include it in your JSX structure. For example:
1import { useState } from 'react';
2import './App.css';
3import CountryInput from './components/CountryInput';
4
5function App() {
6 const [value, setValue] = useState();
7 return (
8 <div className='App'>
9 <CountryInput value={value} setValue={setValue} />
10 <div>
11 {value ? (
12 <>
13 <h3>{`Some information about ${value.name.common}`}</h3>
14 <p>Capital: {value.capital}</p>
15 <p>Population: {value.population} </p>
16 </>
17 ) : (
18 <h3>Select country to get some information</h3>
19 )}
20 </div>
21 </div>
22 );
23}
24
25export default App;
Conclusion

With this React Country Search component, you've integrated real-time data fetching, debouncing for efficient search calls, and a dropdown for selecting countries. Feel free to customize the styles and enhance the functionality based on your specific project requirements. Building such components not only provides a seamless user experience but also showcases the power and flexibility of React in handling asynchronous operations.