0

I have a single-selection Typeahead in my React app, and I'm trying to maintain the user's search input text after they select an option from the dropdown. Currently there may be multiple suggested results from their search input, but selecting one auto-updates the search input to this selection, eliminating the display of alternative options.

My original strategy was to store the search query string in a useState hook and update the Typeahead input with the old value as part of handleSelection, but that doesn't seem possible based on this answer.

const [searchQuery, setSearchQuery] = useState('');

const typeaheadRef = useRef(null);

const handleSelection = (selection:Object[]) => {
...do redux update on selection
typeaheadRef.current.value = searchQuery;
};

return(
<Typeahead
   maxResults={50}
   id="search-people"
   options={filteredPeopleList}
   labelKey={(option: Object) => option?.name ?? ''}
   filterBy={['name']}
   onChange={handleSelection}
   ref={typeaheadRef}
   onInputChange={query => setSearchQuery(query)}
/>)

Note: I am not passing a selected prop to the Typeahead.

1 Answer 1

0

I think what you're trying to do is possible, but there are a couple key pieces you need to update:

  1. Omit the value being passed to the input internally so that it simply maintains whatever the user has entered. You can control this via the renderInput prop.
  2. Change the default filterBy method so that it filters based on the user's input and not the internal value of the input. You can use the searchQuery string you're already storing for this.

Code:

const [searchQuery, setSearchQuery] = useState('');

const typeaheadRef = useRef(null);

const handleSelection = (selection:Object[]) => {
  ...do redux update on selection
};

return (
  <Typeahead
    filterBy={(option) => (
      // Filter by the user's input, not the internal state.
      option.name.toLowerCase().indexOf(searchQuery.toLowerCase()) > -1
    )}
    renderInput={({ value, ...inputProps }) => (
      // Don't pass in `value` coming from internal state
      <TypeaheadInputSingle {...inputProps} />
    )}
    maxResults={50}
    id="search-people"
    options={filteredPeopleList}
    labelKey={(option: Object) => option?.name ?? ''}
    filterBy={['name']}
    onChange={handleSelection}
    onInputChange={query => setSearchQuery(query)}
  />
);

Note: This isn't really how the component is intended to be used and it's possible the above code will result in buggy behavior. At first glance, it's also not a great user experience, since there's no indication a selection has been made, but maybe you're indicating that in some other way.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.