When using multiple indices hits rendered twice once from original indexName, then from targeted indexName

Hi, I am using multiple indices search so I used Index and Configure widget to only target second indexName that I want to receive data from. But it seems that hits array gets retrieved twice.

Let me share my codes.

// Routes.js
// from root component I am using index dev_marketplace_V2

import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { connect } from 'react-redux';
import { isDeviceMobile } from 'state/actions';
import { InstantSearch } from 'react-instantsearch-dom';
import algoliasearch from 'algoliasearch/lite';
import UAParser from 'ua-parser-js';
//...

const ua = UAParser();

const searchClient = algoliasearch(
  '..',
  '...'
);

const algoliaClient = {
  async search(requests) {
    const res = await searchClient.search(requests);
    console.log(res);
    return res;
  },
};

//...

class Routes extends React.Component {
  componentDidMount() {
    this.props.isDeviceMobile(isMobile);
    console.log('isMobile? ', isMobile);
  }
  render() {
    return (
      <Router>
        <InstantSearch
          searchClient={algoliaClient}
          indexName="dev_marketplace_V2"
          refresh={true}
        >
          <Layout>
            <Switch>
              <Route exact path="/" component={Home} />
              <Route exact path="/details/:page/:id" component={Details} />
              <Route exact path="/myaccount" component={MyAccount} />
              <Route exact path="/sell/:id" component={Sell} />
              <Route exact path="/wallet/install" component={WalletLogin} />
              <Route exact path="/wallet/unlock" component={WalletLogin} />
              <Route exact path="/success/listing" component={SuccessListing} />
              <Route
                exact
                path="/success/buy/complete"
                component={SuccessBuyingComplete}
              />
              <Route exact path="/success/buy" component={SuccessBuying} />
              <Route exact path="*" component={Error} />
            </Switch>
          </Layout>
        </InstantSearch>
      </Router>
    );
  }
}

export default connect(
  null,
  { isDeviceMobile }
)(Routes);

On child component I want to receive data only from other index (dev_marketplace_V2_myaccount)

//MyAccount.js => here targeted indexName is dev_marketplace_V2_myaccount

import React, { useState, useEffect } from 'react';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { Index, Configure } from 'react-instantsearch-dom';
import { getCoinbase } from 'state/actions';
import Search from 'components/Search';
import MyAccountSort from 'components/MyAccountSort';
import Sidebar from 'components/Sidebar';
import MyItems from 'components/MyItems';
//...

const MyAccount = ({
  userAccount,
  userBalance,
  plaBalance,
  userLoggedIn,
  history,
}) => {
  const [activeTab, setActiveTab] = useState('myItem');
  const [activeViewType, setActiveViewType] = useState('card');

  const getComponentType = val => {
    setActiveViewType(val);
  };

  useEffect(() => {
    if (!userLoggedIn) {
      history.push('/wallet/install');
    }
  }, [userLoggedIn]);

  if (userLoggedIn) {
    return (
      <div className="myaccount">
        <section className="myaccount__header">
          <div className="container">
            <div className="row">
//...
              </div>
            </div>
          </div>
        </section>
        <section className="myaccount__mydetail">
          <div className="container">
            <nav>
              <div
                className="myaccount__mydetail__header nav nav-tabs"
                id="nav-tab"
                role="tablist"
              >
                <a
                  className={
                    'px-4 py-3 nav-item nav-link text-primary' +
                    (activeTab === 'myItem'
                      ? ' border-bottom-0 myaccount__mydetail__tab--active'
                      : ' border-0')
                  }
                  onClick={() => setActiveTab('myItem')}
                  id="nav-myitem-tab"
                  data-toggle="tab"
                  href="#nav-myitem"
                  role="tab"
                  aria-controls="nav-myitem"
                  aria-selected="true"
                >
                  My item
                </a>
              </div>
            </nav>
            <div className="tab-content position-relative" id="nav-tabContent">
              <div
                className="row tab-pane fade show active"
                id="nav-myitem"
                role="tabpanel"
                aria-labelledby="nav-myitem-tab"
              >
                <Configure filters={`owner:${userAccount}`} />
                <Index indexName="dev_marketplace_V2_myaccount">
                  <Sidebar parentComponent="myaccount" />
                  <div className="myitem--contents">
                    <div className="myitem__searchbar">
                      <Search parentComponent="myaccount" className="col-8" />
                      <MyAccountSort
                        defaultViewType={activeViewType}
                        handleComponentType={getComponentType}
                      />
                    </div>
                    <MyItems
                      parentComponent="myaccount"
                      activeViewType={activeViewType}
                    />
                    <AlgoliaPagination />
                  </div>
                </Index>
              </div>
            </div>
          </div>
        </section>
      </div>
    );
  } else {
    console.log('cannot access to your account, please log in');
    return null;
  }
};

const mapStateToProps = ({ user }) => {
  const { userAccount, userBalance, plaBalance, userLoggedIn } = user;
  return {
    userAccount,
    userBalance,
    plaBalance,
    userLoggedIn,
  };
};
export default withRouter(
  connect(
    mapStateToProps,
    { getCoinbase }
  )(MyAccount)
);
// This component wraps custom hits component

import React from 'react';
import { connectHits, Index, Configure } from 'react-instantsearch-dom';
import CardType from 'components/CardType';
import TableType from 'components/TableType';

const  MyItems = ({ parentComponent, activeViewType }) => {
  let ItemCard;

  activeViewType === 'card'
    ? (ItemCard = connectHits(CardType))
    : (ItemCard = connectHits(TableType));

  return (
    <ul
    >
      <ItemCard parentComponent={parentComponent} />
    </ul>
  );
};

export default  MyItems;

I only want to receive results from second index(dev_marketplace_V2_myaccount) but below component receives hits from original index(which is injected at IndexSearch on Routes.js) and then from second index(from Index widget from MyAccount js).

I don’t know how to figure out this problem. I would appreciate any help to find out any solution for this!

// this component receives hits
// I only want to receive results from second index(dev_marketplace_V2_myaccount) 
import React, { useState, useEffect } from 'react';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import algoliasearch from 'algoliasearch/lite';
import { showLoader } from 'state/actions';
import '../styles/scss/components/_CardType.scss';

const CardType = ({
  parentComponent,
  history,
  hits,
  showLoader,
  userAccount,
}) => {
  const [algoliaData, setAlgoliaData] = useState(null);
  console.log('HITS!', hits);
  useEffect(() => {
    if (hits.length > 0 && parentComponent === 'myaccount') {
      console.log('HITS MYACC', hits);
      const item = hits
        .filter(el => el.owner === userAccount)
        .map(el => (
          <li
            onClick={() => goToDetails(el.objectID)}
            key={el.objectID}
            className={
              (parentComponent === 'myaccount' ? '' : 'col-xl-3') +
              ' ' +
              'col-6 col-md-4 nft-card card-decks'
            }
          >
            <div className="bg-dusk card position-relative">
              <div className="card--height">
                <img
                  onLoad={handleImageLoad}
                  className="card-img-top"
                  src={el.imageURI}
                  alt={el.title}
                />
                <div className="card--tag position-absolute bg-primary font-weight-bold text-white">
                  {el.gametitle}
                </div>
              </div>
              <div className="card-body text-left">
                <h5 className="card__title card-title text-light">
                  {el.title}
                </h5>
                <div>
                  <div className="card__id text-secondary">
                    {el.tokenid}
                  </div>
                  <div className="card__price text-light">Ξ {el.price}</div>
                </div>
              </div>
            </div>
          </li>
        ));

      setAlgoliaData(item);
//,,,
    }
  }, [hits, parentComponent]);

  const handleImageLoad = () => {
    return new Promise(resolve =>
      setTimeout(() => {
        showLoader(false);
        resolve('loaded');
      }, 2000)
    );
  };

  const goToDetails = objectID => {
    history.push({
      pathname: `/details/${parentComponent}/${objectID}`,
    });
  };

  if (algoliaData) {
    console.log(algoliaData);
    return <>{algoliaData}</>;
  }
  return null;
};

const mapStateToProps = ({ user }) => {
  const { userAccount } = user;
  return { userAccount };
};

export default withRouter(
  connect(
    mapStateToProps,
    { showLoader }
  )(CardType)
);

Hi @dev17,
Thank you for reaching out to us.

Thanks for the code but could you kindly put them into a CodeSandbox with minimum code to reproduce your issue please?
That way we can better isolate the issue and investigate the cause of your problem.
You can use the following template:

Please let me know how it goes.
Looking forward to helping your issue.

Hi @eunjae.lee, I finally figured out why. There was a hidden refinement list which used original index name but it was being rendered on MyAccount page as well. So it was the reason which caused multiple api call. In the end the problem was my issue. Thanks for your interest!

1 Like