单页面多AsyncTypeahead添加失败及动态选项分配问题求助
Hey there! I’ve dealt with exactly these two issues using AsyncTypeahead before, so let’s break down how to solve them step by step.
1. Adding Multiple AsyncTypeahead Components on One Page
The most common pitfall here is sharing state (like options or isLoading) across all components. When you do that, every typeahead will update at the same time, which is not what you want.
Instead, you need to track independent state for each component. Use an object in your state where each key maps to the specific state (options, loading status) for that typeahead.
2. Assigning Dynamic Options to Dynamically Created Components
For dynamically generated typeaheads, you need to tie each component’s state to its unique identifier (the key you’re already using for inputProps.id). Here’s a concrete example using a class component:
Step 1: Initialize Component-Specific State
state = { // Each key will store options and isLoading for a single typeahead componentStates: {} };
Step 2: Update the Search Handler to Target Specific Components
Modify your handleSearch method to accept the component’s key, so you know exactly which typeahead’s state to update:
handleSearch = (query, key) => { // Set loading state for the specific component this.setState(prevState => ({ componentStates: { ...prevState.componentStates, [key]: { ...prevState.componentStates[key], isLoading: true } } })); // Replace with your actual API call fetch(`https://your-api-endpoint.com/search?query=${query}`) .then(response => response.json()) .then(data => { // Update options for the specific component and turn off loading this.setState(prevState => ({ componentStates: { ...prevState.componentStates, [key]: { options: data, isLoading: false } } })); }) .catch(() => { // Handle errors by clearing options and turning off loading this.setState(prevState => ({ componentStates: { ...prevState.componentStates, [key]: { options: [], isLoading: false } } })); }); };
Step 3: Render Dynamically with Component-Specific State
When rendering your list of typeaheads, pull the state for each component using its key. If the key doesn’t exist in componentStates yet, default to empty options and no loading:
render() { // Example: dynamically generated list of keys for your typeaheads const dynamicKeys = ['user-search', 'product-search', 'order-search']; return ( <div className="typeahead-container"> {dynamicKeys.map(key => { const { options = [], isLoading = false } = this.state.componentStates[key] || {}; return ( <AsyncTypeahead key={key} labelKey="id" options={options} inputProps={{ id: key }} clearButton={true} minLength={5} isLoading={isLoading} filterBy={filterByCallback} onSearch={(query) => this.handleSearch(query, key)} placeholder="Search..." /> ); })} </div> ); }
Why This Works
- Each
AsyncTypeaheadgets its own isolated state, so searching in one won’t affect the others. - By passing the component’s key to
handleSearch, you ensure only the correspondingoptionsandisLoadingvalues are updated. - Default values (
options = [],isLoading = false) prevent errors when a component is first rendered and hasn’t had a search yet.
I’ve seen several other developers run into this exact issue—usually because they forgot to decouple state between components. This approach should resolve both your problems!
内容的提问来源于stack exchange,提问作者Johnson Samuel

