This content originally appeared on DEV Community and was authored by James Hubert
Hey! I'm on a mission to make 100 React.js projects ending March 31st. Please follow my dev.to profile or my twitter for updates and feel free to reach out if you have questions. Thanks for your support!
Link to the deployed project: Link
Link to the repo: github
Today I wanted to create an autocomplete component in React because I haven't implemented search in React before much less autocomplete. I'm actually curious how other people implement this from scratch because with the Star Wars API it's fairly easy. They have their own search feature that returns an array of JSON results and the number of Star Wars characters any search is going to return is necessarily small. What if your database has 100,000 possible results? I suppose you could put a numeric limit on the results in most databases.
For the basic search component I adapted this Dev.to blog post into a functional component. Rather than use their API, I decided to use a Star Wars character search API that is open and doesn't require a signup that exposes my email.
The structure of the website is simple. It uses an App
component and a Search
component, where the important logic happens. It uses three pieces of state- query
, searchResults
and selectedCharacter
which are all set to empty at initialization:
const [query,setQuery] = useState('');
const [searchResults,setSearchResults] = useState([]);
const [selectedCharacter,setSelectedCharacter] = useState(null);
In the return statement we create a form with a text input for the search feature:
return (
<form className='search-form-container'>
<input
placeholder='Search for...'
onChange={handleInputChange}
value={query}
/>
</form>
)
As the user searches we initiate the API call to the Star Wars API using their search URL query:
const searchURL = 'https://swapi.dev/api/people/?search=';
const getInfo = () => {
console.log('Getting info from API...')
fetch(searchURL+query)
.then(res => res.json())
.then(data => setSearchResults(data.results))
.catch(e => {
console.log({error: e});
});
}
const handleInputChange = (e) => {
setQuery(e.target.value)
if (query && query.length > 0) {
getInfo();
}
}
If results are returned from the API, we populate a ul
element beneath the search box with results. I usually use the standard map method and create a key
prop for the returned JSX children but I wanted to implement this a new way- with the React.Children.toArray()
method. This way, you don't have to create your own key prop.
const results = React.Children.toArray(
searchResults.map((item,idx) => (
<li className='result-item' id={idx} onClick={handleQueryResultClick}>{item.name}</li>
))
)
That looks like the following:
If the user selects one of these li
elements, the index of that element from the original array of results stored in searchResults
will match up with the id of the li
element.
const handleQueryResultClick = (e) => {
const searchResultId = e.target.id;
setSelectedCharacter(searchResults[searchResultId]);
setQuery([]);
}
We then populate select data from that character's search into a div below the search box and clear the query state to remove the ul
element of search results. I did this with a ternary.
<div>
{selectedCharacter ? (
<div className='character-display-container'>
<p><span className='character-info-title'>name:</span> {selectedCharacter.name}</p>
<p><span className='character-info-title'>height:</span> {selectedCharacter.height}</p>
<p><span className='character-info-title'>mass:</span> {selectedCharacter.mass}</p>
</div>
) : (
<p className='no-results-prompt'>There are no results. Try typing something into the search bar above.</p>
)}
</div>
That's it! It was easier than I expected, largely because the API is so easy to use. I highly encourage you to try it.
This content originally appeared on DEV Community and was authored by James Hubert

James Hubert | Sciencx (2021-02-21T06:20:38+00:00) Project 49 of 100 – Search with Autocomplete. Retrieved from https://www.scien.cx/2021/02/21/project-49-of-100-search-with-autocomplete/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.