基于对象数组的React Typeahead/Search/Suggestions组件实现问询
Got it, let's tweak your existing Typeahead component to work with the object array and output the exact format you want. I'll walk you through a complete React implementation step by step.
First, we need to adjust the filtering logic to check against both the label and text properties of each object in your carBrands array. We'll match any item where either property includes the user's search query (case-insensitive for better usability).
Your desired format is [text] [label] with truncated labels when they're too long. We'll create a helper function to truncate the label after a certain number of characters (e.g., 3 characters like your example "Ali...").
Here's a complete functional component that ties it all together:
import { useState } from 'react'; const carBrands = [ { label: "Alice Bowen", text: "name@email.com" }, { label: "John smith", text: "name@email.com" }, { label: "Jenny fey", text: "name@email.com" }, { label: "Peter parker", text: "name@email.com" } ]; const Typeahead = () => { const [searchQuery, setSearchQuery] = useState(''); // Helper to truncate text with ellipsis const truncateText = (text, maxLength) => { if (text.length <= maxLength) return text; return text.substring(0, maxLength) + '...'; }; // Filter the object array based on search query const filteredResults = carBrands.filter(item => { const query = searchQuery.toLowerCase(); return item.label.toLowerCase().includes(query) || item.text.toLowerCase().includes(query); }); return ( <div className="typeahead-container"> <input type="text" value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} placeholder="Search for a contact..." className="search-input" /> {filteredResults.length > 0 && ( <div className="results-list"> {filteredResults.map((item, index) => ( <div key={index} className="result-item"> <span className="result-text">{item.text}</span> {/* Truncate label to 3 characters as in your example */} <span className="result-label">{truncateText(item.label, 3)}</span> {/* Add the separator line after each item except the last one */} {index !== filteredResults.length - 1 && <hr className="separator" />} </div> ))} </div> )} </div> ); }; export default Typeahead;
Key Details:
- Filtering: The
filteredResultsarray checks bothlabelandtextfor the search query, converted to lowercase to make the search case-insensitive. - Truncation: The
truncateTextfunction takes a string and max length, returning the full string if it's short enough, or a truncated version with ellipsis if not. You can adjust themaxLengthparameter (set to 3 in the example) to fit your needs. - Layout: Each result item displays the
textfirst, followed by the truncatedlabel, with a horizontal rule separator between items (excluding the last one).
You can add some basic CSS to make it look cleaner:
.typeahead-container { max-width: 400px; margin: 20px; } .search-input { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; } .results-list { margin-top: 8px; border: 1px solid #ddd; border-radius: 4px; background: white; } .result-item { padding: 10px; display: flex; gap: 8px; align-items: center; } .result-text { font-weight: 500; } .result-label { color: #666; } .separator { border: none; border-top: 1px solid #eee; margin: 0; }
内容的提问来源于stack exchange,提问作者pourushsingh gaur

