How avoid first render of useStats for not to show empty results?

Hi,
I use useStat() hook from react react-instantsearch-hooks-web to display the total results in a box when the page loads. The problem is that in that first load there always arrives a first empty result that shows it for a second with the nb-hits=0 prop by default. Right after comes the actual result with the correct statistic. I want to avoid that first empty result when the page is rendered for the first time.

This is how I’m doing it:


import React, { useState, useEffect } from 'react';
import { Loader } from '../Loader';

import { useConnector } from 'react-instantsearch-hooks-web';
import connectStats from 'instantsearch.js/es/connectors/stats/connectStats';
import type { StatsConnectorParams, StatsWidgetDescription } from 'instantsearch.js/es/connectors/stats/connectStats';

export type UseStatsProps = StatsConnectorParams;

export function useStats(props: UseStatsProps) {
  return useConnector<StatsConnectorParams, StatsWidgetDescription>(connectStats, props);
}

export function Stats(props: { entity: string } & UseStatsProps) {
  const data = useStats(props);
  const [isLoading, setIsLoading] = useState(true);
  console.log('data', data);

  useEffect(() => {
    console.log('useEffect');
    setIsLoading(false);
  }, [data]);

  return (
    <div className="catalog-search__results-info">
      {isLoading ? <Loader /> : `${data.nbHits} ${props.entity} found`}
    </div>
  );
}

Thanks!!!

Hi @rosa.pernia75

This seems like an issue with async API calls – I don’t think your isLoading is quite working yet. I struggle with this myself as a novice React/JavaScript program.

Here’s some code a colleague helped me with for another project. You’ll note the useEffect is inside the component with the data call (in my case usePokemonData, equivalent to your useStats effect).

I then add this effect to my component here:

Perhaps this will help?

Hi @chuck.meyer

After doing several tests with logs, I had the suspicion that it could be an asynchrony problem.
I tried a solution similar to the one you gave me. But a loop is generated. Seems like a problem of this function useConnector<StatsConnectorParams, StatsWidgetDescription>(connectStats, props) .

Thank you so much for the idea!!! I learning react too :sweat_smile:

This has been my attempt. I’ll keep trying.

import React, { useState, useEffect } from 'react';
import { Loader } from '../Loader';

import { useConnector } from 'react-instantsearch-hooks-web';
import connectStats from 'instantsearch.js/es/connectors/stats/connectStats';
import type { StatsConnectorParams, StatsWidgetDescription } from 'instantsearch.js/es/connectors/stats/connectStats';

export type UseStatsProps = StatsConnectorParams;

function useStats(props: UseStatsProps) {
  const [statsData, setStatsData] = useState({
    data: null,
    isLoading: true,
  });

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await useConnector<StatsConnectorParams, StatsWidgetDescription>(connectStats, props);
        setStatsData({
          data: response,
          isLoading: false,
        });
      } catch (err) {
        setStatsData({
          data: null,
          isLoading: false,
        });
      }
    }
    fetchData();
  }, []);

  return statsData;
}

export function Stats(props: { entity: string } & UseStatsProps) {
  const { data, isLoading } = useStats(props);
  console.log('data', data);

  return (
    <div className="catalog-search__results-info">
      {isLoading ? <Loader /> : `${data.nbHits} ${props.entity} found`}
    </div>
  );
}