I'm trying to build an input box where the user will type something and based on the input, a suggestion popup will appear below the input box showing the suggested content. In my code, the suggestions show up just fine, but when I type more, the previous popup doesn't close.
return <div className="border border-gray-400 rounded-md mx-10 my-10 h-10 relative"> <input value={value} onChange={(e) => setValue(e.target.value)} className="w-full border-none absolute inset-0 z-10 outline-none px-2 text-sm bg-transparent" style={{ WebkitTextFillColor: "transparent" }} maxLength={maxLength} /> <div className="text-sm absolute inset-0 flex items-center px-2 whitespace-pre"> {value.split(" ").map((word, i) => { const isHighlighted = word.toLowerCase().includes(suggestions[0]); return ( <div className="relative" key={i}> {isHighlighted ? ( <>{getHighlightedSyntex(word, i)}</> ) : ( getSyntex(word, i) )} {getSuggestions(word)} </div> ); })} </div> </div>
This is where I show my renderings. The getSuggestions function is as follows:
const getSuggestions = (word) => { const matchedPartialSuggestions = suggestions.filter( (item) => word !== "" && item.toLowerCase().startsWith(word.toLowerCase()) ); console.log('va', word, matchedPartialSuggestions) return ( <> {matchedPartialSuggestions.length > 0 && ( <div className="absolute z-10 p-2 bg-white border rounded shadow-lg"> {matchedPartialSuggestions?.map((item, i) => { return <p key={i}>{highlightMatching(word, item)}</p>; })} </div> )} </> ); };
In these functions, I show popups containing search suggestions. I know why the popup won't close because when I enter something that matches the suggestions data, the variable of the getSuggestions function gets the filtered value. That's why the popup won't close. But I only want the search suggestions to show when the input value matches the search suggestion data, otherwise the popup will always be hidden.
P粉3431416332023-09-17 20:49:19
The problem you are facing is that when you continue typing, the previous pop-up suggestions are not cleared.
To fix this issue, you need to manage the visibility of the suggestion popup and control its display. Here's an updated version of your code that should handle this:
return ( <div className="border border-gray-400 rounded-md mx-10 my-10 relative"> <input value={value} onChange={(e) => { setValue(e.target.value); setShowSuggestions(true); // 当输入发生变化时显示建议 }} onBlur={() => { setTimeout(() => setShowSuggestions(false), 200); // 当输入失去焦点时隐藏建议 }} onFocus={() => setShowSuggestions(true)} // 当输入获得焦点时显示建议 className="w-full border-none absolute inset-0 z-10 outline-none px-2 text-sm bg-transparent" style={{ WebkitTextFillColor: "transparent" }} maxLength={maxLength} /> <div className="text-sm absolute inset-0 flex items-center px-2 whitespace-pre"> {value.split(" ").map((word, i) => { const isHighlighted = word.toLowerCase().includes(suggestions[0]); return ( <div className="relative" key={i}> {isHighlighted ? ( <>{getHighlightedSyntex(word, i)}</> ) : ( getSyntex(word, i) )} {showSuggestions && getSuggestions(word)} {/* 当showSuggestions为true时显示建议 */} </div> ); })} </div> </div> );