question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

react instantsearch and react native - nesting connectors within a modal

See original GitHub issue

Hi,

i’m trying to make instantsearch run on a react native project. It is a large product list that can be filtered. Specifically i want to place the filter options in a modal dialog (https://facebook.github.io/react-native/docs/modal.html). After the modal opens, users can select various filter options and then hit ‘Apply Filter’, which closes the modal.

The Problem is that the previous alterations to the search state are gone. Any ideas on how to solve that?

Thank you!

import React, { Component } from 'react';
import { TouchableOpacity, TouchableHighlight, Image, Text, TextInput, Dimensions, Title, Icon, Header, View,  StyleSheet, Modal, ScrollView, ListView, RefreshControl } from 'react-native';


// Algolia Instantsearch
import { InstantSearch } from 'react-instantsearch/native';
import { connectSearchBox, connectInfiniteHits, connectCurrentRefinements, connectStats, connectHierarchicalMenu, connectRefinementList } from 'react-instantsearch/connectors';

// Catalog components
import SearchBox from './searchbox';
import Hits from './hits';

// Modal Content
import CurrentRefinements from './currentrefinements';
import CategoryFilter from './categoryfilter';
import SizeFilter from './sizefilter';
import PriceFilter from './pricefilter';
import ApplyFilter from './applyfilter';

// Pass Components to Algolia Connectors
const ConnectedSearchBox = connectSearchBox(SearchBox);
const ConnectedHits = connectInfiniteHits(Hits);
const ConnectedCurrentRefinements = connectCurrentRefinements(CurrentRefinements);
const ConnectedCategoryFilter = connectHierarchicalMenu(CategoryFilter);
const ConnectedSizeFilter = connectRefinementList(SizeFilter);
const ConnectedPriceFilter = connectMultiRange(PriceFilter);
const ConnectedApplyFilter=  connectStats(ApplyFilter);

class InstantSearch extends Component {

  constructor(props) {
    super(props);
  }

  render() {

      // Retrieve Redux actions and props
      const { filterModalOpen, toggleFilterModal, searchState, setSearchState, openDrawer } = this.props;
   
      return (

        <View>
            <InstantSearch
              appId="latency"
              apiKey="6be0576ff61c053d5f9a3225e2a90f76"
              indexName='ikea'
              searchState = { searchState }
              onSearchStateChange = { (st) => (  setSearchState(st) ) }
            >

              <TouchableOpacity onPress = { () => toggleFilterModal()} >
                <Text> Open Filter Modal </Text>
              </TouchableOpacity>

              <ConnectedSearchBox openDrawer = { openDrawer }/>

              <Modal
                animationType={"slide"}
                transparent={false}
                visible={filterModalOpen}
                onRequestClose={() => {alert("Modal has been closed.")}}
                > 
                <View style = {{ flex : 1 }}>
                    <ConnectedCurrentRefinements  />
                    <ConnectedCategoryFilter attributes = {['category']} />
                    <ConnectedSizeFilter attributeName = "sizes"  />
                    <ConnectedApplyFilter toggleFilterModal = {toggleFilterModal} />
                </View>
              </Modal>

              <ConnectedHits/> 

            </InstantSearch>
        </View>
        );
  }
}

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
mthuretcommented, Mar 28, 2017

Hi @Arcade1080

This occurs because every time a widget is unmounted, then its removed from the search state. When the modal is closed, it unmounts the widgets inside, and then, their refinements are removed from the search state.

We need to think about a new API entry that will allow users to persist a refinement even if the widget is unmounted. That way you will be able to use only virtual widgets without having the need of saving the search state.

As a workaround for now, the way to go is by using virtual widgets along with the searchState and onSearchStateChange props to save the search state except when the modal is closing.

Here’s an example:

 <View style={styles.maincontainer}>
        <InstantSearch
          appId=""
          apiKey=""
          indexName=""
          searchState={this.state.searchState}
          onSearchStateChange={searchState => {
            if (!this.state.isClosing) {
              this.setState({searchState}); //save the searchState except when the modal is closing
            } else {
              this.setState({isClosing: false}); 
            }
          }}
        >
          <ConnectedSearchBox/>
          <VirtualRefinementList attributeName="category" />

          <TouchableHighlight onPress={() => {
            this.setModalVisible(true);
          }}>
            <Text>Show Modal</Text>
          </TouchableHighlight>

          <Modal
            animationType={'slide'}
            transparent={false}
            visible={this.state.modalVisible}
            onRequestClose={() => this.setState({isClosing: true})}
          >
            <View style={{flex: 1, marginTop: 30}}>
              <ConnectedRefinementList attributeName="category" />
              <TouchableHighlight onPress={() => {
                this.setState({isClosing: true});
                this.setModalVisible(!this.state.modalVisible);
              }}>
                <Text>Hide Modal</Text>
              </TouchableHighlight>
            </View>
          </Modal>

          <ConnectedHits/>

        </InstantSearch>
</View>

where VirtualRefinementList is:

const VirtualRefinementList = connectRefinementList(() => null);
0reactions
Arcade1080commented, Apr 11, 2017

Thank you! Will do!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Use React InstantSearch with React Native - Algolia
To leverage InstantSearch features in React Native, you must use connectors. In this guide, you can learn how to build a basic InstantSearch...
Read more >
How do I implement Algolia Search filtering in a React Native ...
Inside the modal the searchState is always falsy because the SearchBox is not mounted. Each time a request happens inside the modal the...
Read more >
react-instantsearch | Yarn - Package Manager
Fast, reliable, and secure dependency management.
Read more >
Search with Algolia in React Native using React InstantSearch
Connectors : The connector handles the business logic and exposes a simplified API to the rendering function (items, refine, widget parameters).
Read more >
react-instantsearch - npm
Lightning-fast search for React and React Native apps, by Algolia. Latest version: 6.38.1, last published: a month ago.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found