react-instantsearch icon indicating copy to clipboard operation
react-instantsearch copied to clipboard

[react-instantsearch-hooks] "isLoading" from `useInfiniteHits`

Open hornta opened this issue 2 years ago • 6 comments

I want to get a loading flag for when I click on "load prev/next" hits so that I can give feedback to my users that something is happening in form of disabling the button and/or showing a spinner.

const {showMore, isLoading}=useInfiniteHits();

return <button onClick={() => {showMore}} disabled={isLoading}>load more</button>

hornta avatar Apr 18 '22 17:04 hornta

We don't yet provide a Hook to retrieve the loading state, but you can implement it based on the results returned by useInfiniteHits().

import React, { useEffect, useState } from 'react';
import { useInfiniteHits } from 'react-instantsearch-hooks';

export function InfiniteHits({ hitComponent: Hit, ...props }) {
  const { isLastPage, showMore, results } = useInfiniteHits(props);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    setIsLoading(false);
  }, [results.page]);

  return (
    <div>
      {/* ... */}
      <button
        onClick={() => {
          setIsLoading(true);
          showMore();
        }}
        disabled={isLoading || isLastPage}
      >
        Show more results
      </button>
    </div>
  );
}

Here's a complete sandbox.

francoischalifour avatar Apr 21 '22 07:04 francoischalifour

Alternatively, useSearchBox also provides isSearchStalled

Haroenv avatar Apr 21 '22 10:04 Haroenv

@Haroenv isSearchStalled gets notified of the stalled status (not the loading status) after 200ms, so the button won't get disabled early enough. (You can decrease it with stalledSearchDelay but I don't recommend it.)

francoischalifour avatar Apr 21 '22 11:04 francoischalifour

We don't yet provide a Hook to retrieve the loading state, but you can implement it based on the results returned by useInfiniteHits().

import React, { useEffect, useState } from 'react';
import { useInfiniteHits } from 'react-instantsearch-hooks';

export function InfiniteHits({ hitComponent: Hit, ...props }) {
  const { isLastPage, showMore, results } = useInfiniteHits(props);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    setIsLoading(false);
  }, [results.page]);

  return (
    <div>
      {/* ... */}
      <button
        onClick={() => {
          setIsLoading(true);
          showMore();
        }}
        disabled={isLoading || isLastPage}
      >
        Show more results
      </button>
    </div>
  );
}

Here's a complete sandbox.

It would be really nice if this could come from the algolia's library API. I would like to avoid any additional setState() calls in my search app because it's quite heavy already.

tk-olari avatar Jun 21 '22 07:06 tk-olari

francoischalifour and updates on this? Would really appreciate to have a loading state!

TobiasLauer avatar Aug 24 '22 20:08 TobiasLauer

Hi @TobiasLauer, implementation of this feature is planned, but we still don't have an estimation regarding availability in the library. Thanks for your patience!

dhayab avatar Aug 26 '22 13:08 dhayab

+1 for adding a property returned from this hook to indicate loading status

atrickofthetail avatar Oct 03 '22 19:10 atrickofthetail

It's not yet documented, but we now have

const { status } = useInstantSearch()

if (status === 'loading' || status === 'stalled') {
  // display loader
}

Haroenv avatar Oct 04 '22 07:10 Haroenv

Thank you @Haroenv! This looks to be exactly what we need.

atrickofthetail avatar Oct 04 '22 14:10 atrickofthetail

As it's been released, I'll close this issue. The general documentation is waiting for a review and will then be available as well on https://www.algolia.com/doc/api-reference/widgets/use-instantsearch/react-hooks/

Haroenv avatar Oct 05 '22 08:10 Haroenv