Render data from multiple indexes using Algolia InstantSearch and Material top tab navigation

I am trying to search multiple indexes e.g users and posts collection with Algolia using one instant search client with a top tab navigation to render data from each index.

Here’s what I have so far:

const SearchScreen = ({ navigation }) => {

  const SearchBar = ({ currentRefinement, refine, isSearchStalled }: SearchBoxProvided) => {
    useEffect(() => {
      navigation.setOptions({
        headerTitleAlign: 'center',
        headerTitle: () => (
          <View style={[tailwind('border border-purple-500 rounded-2xl bg-white w-80')]}>
            <Input
              variant="unstyled"
              size="md"
              borderColor={getColor('purple-500')}
              InputLeftElement={
                <Icon
                  as={<Ionicons name={'search-outline'} />}
                  size={5}
                  style={tailwind('items-center ml-3')}
                  color={getColor('gray-500')}
                />
              }
              InputRightElement={
                currentRefinement != '' ? (
                  <Icon
                    as={<MaterialIcons name="clear" />}
                    size={5}
                    style={tailwind('items-center mr-3')}
                    color={getColor('gray-500')}
                    onPress={() => refine('')}
                  />
                ) : undefined
              }
              placeholderTextColor={getColor('gray-400')}
              style={[tailwind('h-10 items-center text-gray-500')]}
              placeholder="Search..."
              fontSize={'md'}
              autoCapitalize="none"
              autoCorrect={false}
              onChangeText={(value) => {
                refine(value)
              }}
              value={currentRefinement}
            />
          </View>
        ),
      })
    }, [navigation, currentRefinement, refine, isSearchStalled])

    return null
  }

const CustomSearchBox = connectSearchBox(SearchBar)
const SearchScreenItem = ({ indexName }) => {
    return (
      <InstantSearch searchClient={searchClient} indexName={indexName} stalledSearchDelay={500} refresh={true}>
        <CustomSearchBox />
        {indexName == 'posts' ? <CustomInfiniteHits /> : <CustomUserInfiniteHits />}
      </InstantSearch>
    )
  }
  const SearchStack = () => {
    return (
      <TopTab.Navigator
        initialRouteName="World"
        screenOptions={{
          tabBarIndicatorStyle: tailwind('border-purple-800 border-2'),
          tabBarStyle: tailwind('bg-purple-100'),
          tabBarInactiveTintColor: getColor('purple-400'),
          tabBarActiveTintColor: getColor('purple-800'),
          tabBarLabelStyle: {
            textTransform: 'none',
            fontSize: 20,
          },
        }}
      >
        <TopTab.Screen
          name="Something"
          children={() => {
            return <SearchScreenItem indexName={'posts'} />
          }}
          options={{
            tabBarLabel: 'Posts',
          }}
        />
        <TopTab.Screen
          name="Another"
          children={() => {
            return <SearchScreenItem indexName={'users'} />
          }}
          options={{
            tabBarLabel: 'Users',
          }}
        />
      </TopTab.Navigator>
    )
  } 

  return (
    <SafeView style={tailwind('flex-1')}>
      <SearchStack />
    </SafeView>
  )
}

Search Screen component is rendered as a bottom tab navigation and I am trying to add a top tab navigation component with two screens within it.

With my current setup, My custom search bar is being rendered as a header title but I am open to rendering it within my view component. The issue I am having is that my app crashes once I access the search screen component and swipe either of the top tab navigation screens. I am also unable to use the same search query while swiping across each screen in the top tab navigation.

I don’t use React with InstantSearch, so perhaps this will not be that useful. I have created a search interface with tob tab navigation using the InstantSearch JS library and jquery-ui.

Generically, the approach with the regular instant search library is to do your setup by looking at the isFirstRender flag:

// 1. Create a render function
const renderDynamicWidgets = (renderOptions, isFirstRender) => {
  const {
	attributesToRender,
	widgetParams,
  } = renderOptions;

  if (isFirstRender) {
	const ul = document.createElement('ul');
	ul.classList.add('topLevelMenu');
            //etc....etc..do your element setup here

So you will create all your tab elements etc here…then you attach each individual element to it’s tab outside this condition. The order by which Algolia present items is not predictable, so you need to setup all elements on first render, and then you attach the related values in the subsequent passes.

Maybe that will help a bit…

hey, thanks for the suggestion ! I eventually figured it out. My issue was that I wasn’t using the multi indices feature of react instant search + I was trying to render a tab navigator inside an existing component which caused my components to re-render

Cool, glad you got it sorted!