pacocoursey / cmdk

Fast, unstyled command menu React component.
https://cmdk.paco.me
MIT License
9.03k stars 258 forks source link

Empty and Loading state being rendered at the same time #269

Open mbagatini opened 1 month ago

mbagatini commented 1 month ago

I'm facing a problem when working with asyn request options list and search operation. For some reason I could not understand yet, when the records are being fetched, cmdk show both Empty and Loading component at the same time (image below).

Is it a bug or am I doing something wrong?

export const Search = () => {
  const [open, setOpen] = React.useState(false)
  const [search, setSearch] = React.useState('')

  const { data: results, isLoading } = useQuery(
    ['docs', search],
    async (context) => {
      const client = new MeiliSearch({
        host: 'http://127.0.0.1:7700',
        apiKey: 'myMasterKey'
      })
      // An index is where the documents are stored.
      const index = client.index('movies')

      const queryResults = await index.search(context.queryKey[1], { limit: 5 })
      return queryResults
    }
  )

  return (
    <>
      <button onClick={() => setOpen(true)}>
        Search docs
      </button>
      <Command.Dialog
        shouldFilter={false}
        open={open}
        onOpenChange={setOpen}
        label="Global Command Menu"
      >
        <Command.Input
          value={search}
          onValueChange={setSearch}
        />

        <Command.List>
          {isLoading && <Command.Loading>Carregando…</Command.Loading>}
          {results?.hits.map((hit) => (
            <Command.Item key={hit.id} value={hit.title}>
              <h4>{hit.title}</h4>
              <span>{hit.overview}</span>
            </Command.Item>
          ))}

          <Command.Empty>Nenhuma opção disponível</Command.Empty>
        </Command.List>
      </Command.Dialog>
    </>
  )
}

Waiting request to resolve:

Captura de tela de 2024-05-27 14-12-07

matusca96 commented 1 month ago

did you try to move the Command.Empty to outside the Command.List?

mbagatini commented 1 month ago

@matusca96 yes I tried, but the behaviour didn't change. For now, I had to make this change in order to work properly:

        <Command.List>
          {isLoading && <Command.Loading>Carregando…</Command.Loading>}
          {results?.hits.map((hit) => (
            <Command.Item key={hit.id} value={hit.title}>
              <h4>{hit.title}</h4>
              <span>{hit.overview}</span>
            </Command.Item>
          ))}

           {isLoading ? (
                <Command.Empty />
            ) : (
                <Command.Empty>Nenhuma opção disponível</Command.Empty>
            )}

        </Command.List>