Problem Description:
I’m working on implementing a search bar in my React application. The search bar should show a list of suggestions when users type in the input field. These suggestions should be selectable, and when a user clicks on a suggestion, it should set the text of the input field to the selected suggestion.
Code:
I have implemented the search bar using React and have included the relevant code below:
const SearchBar = () => {
const [searchQuery, setSearchQuery] = useState("");
const [showSuggestion, setShowSuggestion] = useState(false);
const [searchSuggetions, setsearchSuggetions] = useState([]);
useEffect(() => {
console.log("api called");
const timer = setTimeout(() => searchSuggestions(), 200);
return () => {
clearTimeout(timer);
};
}, [searchQuery]);
const searchSuggestions = async () => {
const response = await fetch(
`http://suggestqueries.google.com/complete/search?client=firefox&ds=yt&q=${searchQuery}`
);
const json = await response.json();
setsearchSuggetions(json[1]);
};
// Function to handle suggestion item click
const handleSuggestionClick = (result) => {
setSearchQuery(result);
setShowSuggestion(false); // Close suggestions after selection
};
const handleSearch = () => {
console.log("called handle search");
};
return (
<>
<div className="m-2 border-2 rounded-full border-violet-500 w-60 h-8 text-violet-500 items-center inline-flex static z-10">
<input
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value.toLocaleLowerCase())}
onFocus={() => {
setShowSuggestion(true);
}}
onBlur={() => {
setShowSuggestion(false);
}}
type="text"
placeholder="Find news"
className="ml-3 focus:outline-none focus:ring-violet-300 bg-gray-900 "
/>
<button className="hover:text-violet-700" onClick={handleSearch}>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth="1.5"
stroke="currentColor"
className="w-6 h-6"> >
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
/>
</svg>
</button>
{showSuggestion && (
<div className="mt-72 w-52 absolute rounded-xl bg-slate-50 z-10">
{searchSuggetions.map((result, index) => (
<div key={index}>
<ul>
<li className="bg-slate-50 border hover:bg-slate-200 rounded-xl inline-flex cursor-pointer z-20"
onClick={() => {
console.log(result);
handleSuggestionClick(result);
}}
>
<svg xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth="1.5"
stroke="currentColor"
className="w-5 h-5"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
/>
</svg>
<span className="w-48">{result}</span>
</li>
</ul>
</div>
))}
</div>
)}
</div>
</>
);
};
2
Answers
In my case, the problem is occurred due to onBlur event. which is destroying the element from dom due to the selected suggestion not working after clicking on the item removed onBlur event will resolve the issue.