downshift-js / downshift

🏎 A set of primitives to build simple, flexible, WAI-ARIA compliant React autocomplete, combobox or select dropdown components.

Home Page:http://downshift-js.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[discussion] items is initially empty array in useCombobox

alnilam4 opened this issue · comments

  • downshift 8.3.1:
  • node 18.15.0:
  • npm 9.5.0:

Relevant code or config

const {
      inputValue,
      selectedItem,
      getToggleButtonProps,
      getLabelProps,
      getMenuProps,
      getItemProps,
      getInputProps,
    } = useCombobox({
      items, // empty array on initial render
      onInputValueChange({inputValue}) {
        setItems(books.filter(getBooksFilter(inputValue)))
      },
      itemToString(item) {
        return item ? item.title : ''
      },
    })

What you did/ What Happens:
I am trying to create a combobox using the useCombobox hook. The issue is that my items array is coming from an api, so upon initialization, my items array is empty. I'm trying to understand the best way to handle this scenario.

Problem description:
There doesn't seem to be a baked in way for useCombobox to handle incoming values for the items array. So if my items array is empty on first render, it will remain empty unless I implement one of the options listed below.

Suggested solution:
The way I see it, I have these options:

  1. Create a skeleton combobox, and then when my items array is populated, render my combobox
  2. Use a key to force rerender my combobox when new items are passed in
  3. Write a useEffect within my combobox that updates my items once the array is populated
  4. Manage selectedItem with a piece of state

Are any of these solutions preferred, or is there another solution that I am missing?

Why not use state value for the items? And when the API call returns, setItems(newItems), then it will rerender and it should work.

@silviuaavram so you are suggesting using a useEffect to update items? Because if I do something like:

const [items, setItems] = useState(options);

items will be initialized as an empty array when options is passed in as an empty array on first render. To be clear, I'm calling the api from outside the combobox and passing in the returned options as a prop.