4

My Google Books clone application has a user submit their inputted query, then the response data is displayed.

I'd like to implement Downshift's search autocomplete feature so that as the user types their query, a drop down list of suggestions matching their current query is listed. Clicking on a list item from the drop down suggestion list should update the input query, then fetch data for that query. I desire the same behavior as Google Books

The data from the example in the Downshift docs is hard-coded. In my case, data is empty prior to the fetch.

I figured I'd need to create a suggestions object and define the useCombobox logic to fetch suggestions on every input change. Then assign handleBookFetch to the drop down list's items' onClick. With this attempt, I receive TypeErrorCannot read property 'length' of undefined.

I'm having trouble trying to figure out how to use it in my instance. How do I go about fetching suggestions as the user types a query into the input, then update the query value with the clicked suggestion and also fetch the query for the clicked suggestion? CodeSandbox

const [query, setQuery] = useState("");
const [books, setBooks] = useState({ items: [] });
const [suggestions, setSuggestions] = useState({ suggestionItems: [] });

useCombobox({
    suggestions: suggestions,
    onInputValueChange: ({ inputValue }) => {
      const fetchSuggestions = async () => {
        try {
          const result = await axios.get(`${API_BASE_URL}?q=${query}`);
          setSuggestions(result.data);
        } catch (isError) {
          setIsError(true);
        }
      };
      fetchSuggestions();
      setSuggestions(
        suggestions.suggestionItems.filter((suggestionItem) =>
          suggestionItem.toLowerCase().startsWith(inputValue.toLowerCase())
        )
      );

const handleBookFetch = (event) => {
  const fetchBooks = async () => {
    try {
      const result = await axios.get(`${API_BASE_URL}?q=${query}`);
      setBooks(result.data);
    } catch (isError) {
      setIsError(true);
    }
  };
  fetchBooks();
};

<form onSubmit={handleBookFetch}>
  <div className={comboboxStyles} {...getComboboxProps()}>
    <input
      type="text"
      value={query}
      onChange={(event) => setQuery(event.target.value)}
      {...getInputProps()}
    />
    <button
      type="button"
      {...getToggleButtonProps()}
      aria-label="toggle menu"
    >
      &#8595;
    </button>
    <button type="submit">Search</button>
  </div>

  <ul {...getMenuProps()} style={menuStyles}>
    {isOpen &&
      suggestions.suggestionItems.map((book, index) => (
        <li
          style={
            highlightedIndex === index
              ? { backgroundColor: "#bde4ff" }
              : {}
          }
          key={`${book}${index}`}
          onClick={handleFetchBook}
          {...getItemProps({ book, index })}
        >
          {book.volumeInfo.title}
        </li>
      ))}
  </ul>
</form>
ln09nv2
  • 965
  • 4
  • 19
  • 35

0 Answers0