⚡️ Lightning-fast search for React and React Native applications, by Algolia.

Overview

React InstantSearch

React InstantSearch is a library for building blazing fast search-as-you-type search UIs with Algolia.


Version Build Status License Downloads

React InstantSearch is a React library that lets you create an instant-search result experience using Algolia’s search API. It is part of the InstantSearch family:

React InstantSearch | InstantSearch.js | Angular InstantSearch | Vue InstantSearch | InstantSearch Android | InstantSearch iOS

Why

You should be using React InstantSearch if you want to:

  • Design search experiences with best practices
  • Customize your components at will
  • Follow React principles

Installation

React InstantSearch is available on the npm registry. It relies on algoliasearch to communicate with Algolia APIs.

yarn add react-instantsearch-dom algoliasearch
# or
npm install react-instantsearch-dom algoliasearch

Getting started

Using React InstantSearch is as simple as adding these components to your app:

import React from 'react';
import ReactDOM from 'react-dom';
import algoliasearch from 'algoliasearch/lite';
import { InstantSearch, SearchBox, Hits } from 'react-instantsearch-dom';

const searchClient = algoliasearch(
  'latency',
  '6be0576ff61c053d5f9a3225e2a90f76'
);

const App = () => (
  <InstantSearch
    indexName="bestbuy"
    searchClient={searchClient}
  >
    <SearchBox />
    <Hits />
  </InstantSearch>
);

Edit on CodeSandbox

To learn more about the library, follow the getting started guide.

Documentation

The documentation is available on algolia.com/doc.

Demos

E-commerce Media Travel
E-commerce demo preview Media demo preview Tourism demo preview

See more examples on the website.

Playground

You can get to know React InstantSearch on this playground.

Start by adding components and tweaking the display. Once you get more familiar with the library, you can learn more advanced concepts in our guides.

Troubleshooting

Encountering an issue? Before reaching out to support, we recommend heading to our FAQ where you will find answers for the most common issues and gotchas with the library.

Contributing

We welcome all contributors, from casual to regular. You are only one command away to start the developer environment, read our CONTRIBUTING guide.

License

React InstantSearch is MIT licensed.

Comments
  • Add react hooks

    Add react hooks

    Problem:

    Connector HOCs add boilerplate and can be unwieldy. When you have an existing component already the modification to make it connected is a hassle. It also interferes with Flow type-checks because it adds "invisible" props and is hard to compose when you need multiple things.

    For example:

    // Base component
    const Title = () => {
      return <h1>Search results</h1>;
    };
    
    // With results
    import { connectStateResults } from "react-instantsearch/connectors";
    const Title = ({ searchResults }) => {
      return <h1>{searchResults.hits.length} search results</h1>;
    };
    export default connectStateResults(Title);
    

    Redacted from these examples is Flow type checking and our styles HOC that makes it even more messy.

    Solution:

    React hooks offer a more encapsulated and concise way to do this:

    // With results from hook
    import { useStateResults } from "react-instantsearch/hooks";
    const Title = () => {
      const searchResults = useStateResults();
      return <h1>{searchResults.hits.length} search results</h1>;
    };
    export default Title;
    

    It is also much easier to deal with composing multiple things like results and searchState:

    // With results and searchState from hook
    import { useStateResults, useSearchState } from "react-instantsearch/hooks";
    const Title = () => {
      const searchResults = useStateResults();
      const searchState = useSearchState();
      return <h1>{searchResults.hits.length} search results for {searchState.query}</h1>;
    };
    export default Title;
    
    // Or alternatively in one:
    import { useSearch } from "react-instantsearch/hooks";
    const Title = () => {
      const { searchState, searchResults } = useSearch();
      return <h1>{searchResults.hits.length} search results for {searchState.query}</h1>;
    };
    export default Title;
    

    This seems like a small change but having the Algolia parts decoupled from the props and export makes a big difference in aggregate.

    Feedback 
    opened by GriffinSauce 33
  • In some cases there are multiple identical requests

    In some cases there are multiple identical requests

    Do you want to request a feature or report a bug?

    bug

    Bug: What is the current behavior?

    a single refinement (any of them) cases N requests with the exact same parameters

    Bug: What is the expected behavior?

    one request per exact same parameters

    What is the version you are using? Always use the latest one before opening a bug issue.

    4.0.10

    This is visible in

    As discussed with @vvo, we should deduplicate requests either at the React InstantSearch or Helper level, since this might be hard to solve otherwise.

    Type: ❤️ Bug Difficulty: ❄️❄️❄️ hard 
    opened by Haroenv 30
  • Feature Request - Ability to prevent search on init

    Feature Request - Ability to prevent search on init

    By default <InstantSearch> performs search with an empty query on init.

    Feature: What is your use case for such a feature? Performance and network optimization. Currently page doesn't finish loading until this initial search is finished. Also, I want to prevent searches with less than a few characters.

    Feature: What is your proposed API entry? The new option to add? What is the behavior?

    This is available in instantsearch.js with the searchFunction hook. Docs: https://community.algolia.com/instantsearch.js/v1/documentation/#hide-results-on-init

    I'd love if that hook can be used via a prop on <InstantSearch>. Ideally, every possible option for instantsearch.js would automatically be usable on <InstantSearch>.

    Thank you!

    Type: Feature request ♨ API Difficulty: ❄️❄️ medium Feedback 
    opened by flybayer 28
  • docs(refining-hits): add a tutorial on how to refine within hits

    docs(refining-hits): add a tutorial on how to refine within hits

    this is a guide that finishes with https://codesandbox.io/embed/oY1klpZYB

    fixes #244 and is obviously quite advanced

    can be found in the deploy preview under guide/Refining_hits.html

    Documentation: Guide 
    opened by Haroenv 27
  • Error: Unable to retrieve InstantSearch's server state in `getServerState()`. Did you mount the <InstantSearch> component?

    Error: Unable to retrieve InstantSearch's server state in `getServerState()`. Did you mount the component?

    🐛 Bug description

    Hey folks, having some issues with SSR and the getServerState function. I followed the steps from the docs and it's still the same. I cannot set Sandbox since it's a private repo, and if I do it from scratch I cannot reproduce the issue. I'll provide some screenshots below, maybe you see something I don't.

    💭 Expected behavior

    Is there any other way to connect the provider with the InstantSearch instance? What is the other best way to fetch initial results on the serverSide?

    🖥 Screenshots

    Screenshot 2022-08-29 at 09 12 43 Screenshot 2022-08-29 at 09 12 51

    Environment

    • React InstantSearch Hooks version: 6.31.1
    • React version: 17.0.2
    • Browser: Brave Version 1.41.100 Chromium: 103.0.5060.134 (Official Build) (x86_64)
    • OS: macOS
    opened by sasastevcic 25
  • Maximum call stack size exceeded. Related to cache ?

    Maximum call stack size exceeded. Related to cache ?

    Describe the bug 🐛

    I got a 500 from SSR response. In my log I get RangeError: Maximum call stack size exceeded

    To Reproduce 🔍

    Infortunately, I have only this problem on production, not on staging or local.

    If I restart my instance, everything back to normal. My memory was around 25%, I have a total o 2040 mo for my instance.

    So I assume it's a problem on Algolia's cache.

    Environment:

    Next JS 9.3.4, Algolia javascript 4.1, ReactInstantSearch 6.4.0.

    Never had the problem with Algolia 3.35.1 and ReactInstanceSearch 6.3.0

    Additional context

    14:30:24
    RangeError: Maximum call stack size exceeded
    RangeError: Maximum call stack size exceeded
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    14:30:24
    at client.search (/usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:344:50)
    14:30:24
    at /usr/src/app/node_modules/react-instantsearch-core/dist/cjs/core/createInstantSearchManager.js:348:29
    14:30:24
    at Object.get (/usr/src/app/node_modules/@algolia/cache-common/dist/cache-common.cjs.js:43:27)
    
    opened by YoannDelpierre 25
  • Introduce a new API to handle conditional display use case

    Introduce a new API to handle conditional display use case

    Currently, when some conditional display is needed (like a no results page), you're forced to use the createConnector API.

    This API is very internal to react-instantsearchand even if, for performing some conditional display you only touch its surface, it shouldn't be needed by our end user. We need a dedicated API.

    I can see several options:

    1. Easiest solution, you test the condition and rendered the children if it match.
    <If condition={(props, searchState) => searchState.query}>QUERY</If>
    <If condition={(props, searchState) => !searchState.query}>No Query</If>
    
    1. A more complex version handling else use case. We can use the context to store if a condition has matched.
    <Choose>
        <When condition={(searchState, searchResults) => searchState.query}>QUERY</When>
        <Otherwise>NO QUERY</Otherwise>
    </Choose>
    
    1. Another version (based on react-router API), that render the first matching condition. (Or every condition, but then don't see the point versus simple If).
    <Switch>
       <When condition={(searchState, searchResults) => searchState.query}>QUERY</When>
       <When condition={(searchState, searchResults) => !searchState.query}>NO QUERY</When>
    </Switch>
    

    condition is a function that takes searchState and searchResults to still give the maximum of flexibility.

    For the record what we use to have before the first release was something like:

    <NoResults>, <Results>, <Query>, <NoQuery/>... this wasn't very extensible.

    WDYT?

    ♨ API 
    opened by mthuret 22
  • NextJS static page with rewrite rule -> error on refine

    NextJS static page with rewrite rule -> error on refine

    🐛 Bug description

    Refine in a nextJS static page throw this error if you defined a next.js rewrite rule: Error: Cannot refine the undeclared facet brand; it should be added to the helper options facets, disjunctiveFacets or hierarchicalFacets

    🔍 Bug reproduction

    Steps to reproduce the behavior:

    1. Put a rewite rule in your next.config.js
    2. Browse a static page including algolia search
    3. Click on a refinement in the left sidebar
    4. See error

    Live reproduction:

    https://codesandbox.io/s/quizzical-night-mjlw22

    💭 Expected behavior

    The refinement should be applied correctly

    🖥 Screenshots

    image

    Environment

    • React InstantSearch Hooks version: 6.28.0
    • React version: 18.1.0

    Additional context

    I think that the problem is started with the migration to useSyncExternalStore in useInstantSearchApi because I noticed that in the case mentioned above search.dispose() function is called after the page load. Is it possible that migrating from useEffect to useSyncExternalStore+useCallback you forgot to remove the old cleanup function and actually it's invoked accidentally in some cases?

    image
    opened by matteorigotti 21
  • [Unhandled promise rejection: Error: Uncaught, unspecified

    [Unhandled promise rejection: Error: Uncaught, unspecified "error" event. ([object Object])]

    🐛 Bug description

    I'm using React Native Expo Project. On android emulator, I'm getting this error. I followed the documentation same as here . But On real device and Expo Go app, it is working.

    [Unhandled promise rejection: Error: Uncaught, unspecified "error" event. ([object Object])]
    at node_modules\@algolia\events\events.js:62:18 in EventEmitter.prototype.emit
    at node_modules\instantsearch.js\cjs\lib\InstantSearch.js:456:8 in mainHelper.on$argument_1
    at node_modules\@algolia\events\events.js:81:8 in EventEmitter.prototype.emit
    at node_modules\algoliasearch-helper\src\algoliasearch.helper.js:1360:2 in AlgoliaSearchHelper.prototype._dispatchAlgoliaError  
    at node_modules\promise\setimmediate\core.js:37:13 in tryCallOne
    at node_modules\promise\setimmediate\core.js:123:24 in setImmediate$argument_0
    at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:248:12 in _allocateCallback$argument_0
    at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:112:14 in _callTimer
    at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:162:14 in _callReactNativeMicrotasksPass
    at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:413:41 in callReactNativeMicrotasks
    at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:391:6 in __callReactNativeMicrotasks
    at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:133:6 in __guard$argument_0
    at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:368:10 in __guard
    at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:132:4 in flushedQueue
    

    🔍 Bug reproduction

    Steps to reproduce the behavior: React InstantSearch Hooks throwing me error on android studio emulator react native expo project.

    Live reproduction:

    https://codesandbox.io/s/github/algolia/react-instantsearch/tree/master/examples/hooks

    💭 Expected behavior

    Please resolved this issue as soon as possible.

    🖥 Screenshots

    image

    Environment

    • React InstantSearch Hooks version: 6.29.0
    • React version: 17.0.2
    • Browser: Android Studio Emulator Expo
    • OS: Windows

    Additional context

    opened by SohelIslamImran 19
  • Redux state change toggles searching prop from Hits connected to connectSearchState

    Redux state change toggles searching prop from Hits connected to connectSearchState

    I'm working on a shopping cart system and have passed a redux state and actions to a hits widget that is connected to connectStateResults. On each hit I have a quantity +/- button and whenever I press either it triggers the searching prop causing my spinner to show with a large delay. Maybe I've done something wrong here, but this shouldn't be happening.

    Here's my code example:

    export const HitsSearching = ({cart, decrementItem, incrementItem, onPressHit, hits, hasMore, refine, uid, navigation, fieldOne, fieldTwo, fieldThree, fieldFour, usersRef, chatsRef, searching}) => {
      const onEndReached = function() {
        if (hasMore) {
          refine();
        }
      };
    
      if(searching){
        return (
          <Spinner/>
        )
      } else {
        return(
            <FlatList
              data={hits}
              onEndReached={onEndReached}
              keyExtractor={(item, index) => item.objectID}
              ItemSeparatorComponent={Separator}
              renderItem={({ item }) => {
                return (
                  <TouchableOpacity onPress={() => onPressHit(item)}>
                    <View style={styles.itemRowsContainer}>
                      <View style={{flex:1, flexDirection: 'column'}}>
                        <View style={styles.imageAndTextContainer}>
                          <View style={{flexDirection: 'row'}}>
                            <Image 
                              source={{ uri: item.image.thumb.url}} 
                              style={styles.image}
                              resizeMode={'cover'}/>
                            <View style={{justifyContent: 'flex-start', paddingLeft: 8, flexDirection: 'column'}}>
                              <Text style={styles.itemHeader1}>
                                <Highlight attributeName={fieldOne} hit={item} />
                              </Text>
                              <Text style={styles.itemHeader2}>
                                <Highlight attributeName={fieldTwo} hit={item} />
                              </Text>
                              <Text style={styles.itemHeader2}>
                                <Highlight attributeName={fieldThree} hit={item} />
                              </Text>
                            </View>
                          </View>
                          <Text style={styles.itemHeader2}>
                            Distance
                          </Text>
                        </View>
                        <View style={{flexDirection: 'row', paddingTop: 8, justifyContent: 'space-between'}}>
                          <View style={{paddingRight: 10}}>
                            <Text style={styles.itemDescription}>
                              {/*<Highlight attributeName={description} hit={item} />*/}
                              Desrcription
                            </Text>
                          </View>
                                <View style={styles.cartQuantityButton}>
                                  <TouchableOpacity onPress={() => decrementItem(item.docId)}>
                                    <Icon2 name= 'minus' size={Styles.primaryIconSize} color={Colors.primaryGrayColor}/>
                                  </TouchableOpacity>
                                  <Text style={[styles.itemHeader1, {color: Colors.primaryGrayColor}]}>
                                    {cart.items[item.docId].quantity}
                                  </Text>
                                  <TouchableOpacity onPress={() => incrementItem(item.docId)}>
                                    <Icon2 name='plus' size={Styles.primaryIconSize} color={Colors.primaryGrayColor}/>
                                  </TouchableOpacity>
                                </View>
                        </View>
                      </View>
                    </View>
                  </TouchableOpacity>
                );
              }}
            />
        );
      }
    };
    
    export const HitsConnected =  connectInfiniteHits(connectStateResults(HitsSearching));
    

    The widget is called like this from a parent component:

    	return (
                <View style={styles.container}>
                    <InstantSearch
                        appId={algoliaAppId}
                        apiKey={algoliaApiKey}
                        indexName={currentIndex}
                        root={{
                          Root: View,
                          props: {
                            style: {
                              flex: 1
                            }
                          }
                        }}>
                                    <HitsConnected
                                        fieldOne="itemName"
                                        fieldTwo="price"
                                        fieldThree="companyName"
                                        fieldFour="description"
                                        uid={this.user.uid}
                                        navigation={this.props.navigation}
                                        usersRef={this.usersRef}
                                        chatsRef={this.chatsRef}
                                        onPressHit={this.onPressItem}
                                        incrementItem={this.props.incrementItem}
                                        decrementItem={this.props.decrementItem}
                                        cart={this.props.cart}/>
                    </InstantSearch>
                </View>
    )
    
    opened by rtman 17
  • React 18 seems to break components using connectHits and Suspense

    React 18 seems to break components using connectHits and Suspense

    🐛 Bug description

    I have a custom component using connectHits. Inside this component I'm fetching data from another server using Relay. This works fine in React 17, but it breaks in the React 18 beta. The component wrapped in connectHits stops receiving hits after it has received data from Relay one time.

    opened by mellson 16
  • wip: introduce parentIndexId

    wip: introduce parentIndexId

    This would be useful for cases like https://github.com/algolia/react-instantsearch/discussions/3689#discussioncomment-4251317 where the cascade is working against your implementation.

    The reason this is WIP is because I think without having a bare root (without the workaround in App.tsx) you still need to prevent searches on the main index and that's still fairly "ugly". If InstantSearch would have an option to prevent mainIndex from searching (so actually having an array of root indices instead of a single one) it would be much more useful

    opened by Haroenv 2
  • `createURL` always returns root url when server-rendering (SSR)

    `createURL` always returns root url when server-rendering (SSR)

    🐛 Bug description

    createURL produces incorrect URLs on the server (it's always root URL). The same applies to standard components from react-instantsearch-hooks-web: Pagination, etc.

    🔍 Bug reproduction

    Steps to reproduce the behavior:

    1. Fork [SSR example with Remix
    2. Edit app/root.tsx and comment out <Scripts />
    3. Refresh the page and inspect the hrefs of pagination links (.ais-Pagination-link)

    Live reproduction:

    https://codesandbox.io/s/zen-cache-7cyfjo?file=/app/root.tsx

    💭 Expected behavior

    createURL should produce correct URLs when server rendering, without running any code on the client.

    🖥 Screenshots

    Environment

    • React InstantSearch Hooks version: 6.38.1
    • React version: 17.0.2
    • Browser: Chrome
    • OS: MacOS

    Additional context

    opened by sixers 0
  • Performance regression from dom to hooks

    Performance regression from dom to hooks

    🐛 Bug description

    I noticed that performance of updating the search query became quite a bit worse when I changed from -dom to -web-hooks.

    Some functions that seem responsible for pretty much all of the wait time:

    • escapeHits
    • recursiveEscape
    • getWidgetRenderState

    Screenshot 2022-11-17 at 22 07 00

    Screenshot 2022-11-17 at 22 18 03

    🔍 Bug reproduction

    Steps to reproduce the behavior:

    1. Set up a basic React-Instantsearch with Hits and SearchBox with react-instantsearch-dom
    2. Start typing, note the quick rendering
    3. Switch to react-instantsearch-dom
    4. Start typing, note the slower rendering

    Sorry for the lack of demo repo, my project is currently closed source. I'll try to dive in deeper, I'll update this issue

    Some findings / thoughts:

    • The issue scales with the amount of HitsPerPage
    • Even if my custom Hit component returns null, the issue is bad, so it's not really the rendering part, I think.
    • It may have something to do with my relatively large documents, which contains many keys (about 100 KV combos)

    Live reproduction:

    https://codesandbox.io/s/github/algolia/react-instantsearch/tree/master/examples/hooks

    Environment

    • React InstantSearch Hooks version: 6.38.0
    • React version: 18.2.0
    • Browser: Firefox 108
    • OS: MacOS
    opened by joepio 3
  • `GoogleMapsLoader` instantly unmounts, not rendering Map

    `GoogleMapsLoader` instantly unmounts, not rendering Map

    Hi there! First off, thanks for maintaining this really nice library :)

    I'm kind of stuck with react-instantsearch-dom, as you can read below, but maybe I should migrate to react-instantsearch-hooks-web anyway.

    🐛 Bug description

    I'm trying to render a map using GoogleMapsLoader and GeoSearch, but fail to render anything. I've set a height in the parent, so that's not it.

    There are no errors in the console, and the network responses look good - I can see that Google's API is responding with 200s. And window.google is in fact a google object, so I suppose the googles js code is running just fine.

    I've tried reproducing the bug in CodeSandbox, but to no avail. It just works there.

    The lambda in the children of GeoSearch is never called. If I put a console.log in, It never shows. So for some reason something goes wrong in GoogleMapsLoader.

    This condition is always false, because this.isUnmounting seems to always be true in my case.

    // GoogleMapsLoader.js 
            if (!this.isUnmounting) {
              this.setState(() => ({
                google: window.google,
              }));
            }
    

    So the google state is never set, and this always returns null:

          if (!this.state.google) {
            return null;
          }
    

    this.isUnmounting is practically always set to true, because componentWillUnmount is called early on.

      componentWillUnmount() {
        this.isUnmounting = true;
      }
    

    I thought this is supposed to be called only when a component will unmount?

    Code

    import React from "react";
    import {
      GoogleMapsLoader,
      GeoSearch,
      Control,
      Marker,
    } from "react-instantsearch-dom-maps";
    import { mapsKey } from "./config";
    import './Map.css';
    
    export const Map = () => {
      return (
        <div className="Map">
          <GoogleMapsLoader apiKey={mapsKey}>
            {(google) => {
              console.log('google', google);
    
              return (
              <GeoSearch google={google}>
                {({ hits }) => (
                  <div>
                    <Control />
                    {hits.map((hit) => (
                      <Marker key={hit.objectID} hit={hit} />
                    ))}
                  </div>
                )}
              </GeoSearch>
            )}}
          </GoogleMapsLoader>
        </div>
      );
    };
    
    

    Environment

    • React InstantSearch version: 6.38.0
    • React version: 18.2
    • Browser: Firefox and chrome
    • OS: MacOS latest, m1
    opened by joepio 5
  • Empty/No Result Boundary - InstantSearch Hooks - Warning

    Empty/No Result Boundary - InstantSearch Hooks - Warning "Can't perform a React state update on an unmounted component."

    🐛 Bug description

    When following the code examples for implementing an Empty Results Boundary (https://www.algolia.com/doc/guides/building-search-ui/going-further/conditional-display/react-hooks/#handling-empty-queries), an error is thrown when a term is searched for, and then deleted from the search box (to replicate - type term and delete).

    Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

    The same is replicable when following the code examples for a No Results Boundary (documentation at same link as above).

    This is found in a statically rendered search page in a next application implementing InstantSearch Hooks.

    🔍 Bug reproduction

    Steps to reproduce the behavior:

    1. Spin up a sandbox next site
    2. Create a search page and implement the following code for the page component:
    function App(props) {
      return (
        <InstantSearch {...props}>
          <SearchBox />
          <EmptyQueryBoundary fallback={null}>
            <Hits />
          </EmptyQueryBoundary>
        </InstantSearch>
      );
    }
    
    function EmptyQueryBoundary({ children, fallback }) {
      const { indexUiState } = useInstantSearch();
    
      if (!indexUiState.query) {
        return fallback;
      }
    
      return children;
    }
    
    1. Start typing your search term
    2. Delete the search term from the search box
    3. Inspect console to see warning error.

    💭 Expected behaviour

    Wouldn't expect to see the error

    🖥 Screenshots

    Screen Shot 2022-11-02 at 1 13 26 PM

    Environment

    • "react-instantsearch-hooks-web": "^6.34.0",
    • React version: 17.0.2
    • Browser: Version 107.0.5304.62 (Official Build) (arm64)
    • OS: macOS Monterey
    opened by ventureweb-ojw 3
  • React InstantSearchSSRProvider hooks - Gatsby SSG

    React InstantSearchSSRProvider hooks - Gatsby SSG

    🐛 Bug description

    I'm trying to implement algolia with Gatsby SSG functionality into our platform via a POC.

    🔍 Bug reproduction

    Steps to reproduce the behavior:

    1. Get data through xml, and then call serverdata is the default value of InstantSearchSSRProvider, the hook has no initialized data, and the ui will not change.
    2. The InstantSearchSSRProvider component cannot implement the Gatsby SSG function without passing in the default value

    Live reproduction:

    https://codesandbox.io/p/github/Lium-Yu/gatsby-algolia/main?file=%2Fsrc%2Fpages%2Findex.js

    github 🌰

    💭 Expected behavior

    InstantSSRProvider should be able to give initial value, or give me other solutions, thanks.

    🖥 Screenshots

    image

    image

    Environment

    image

    opened by Lium-Yu 0
Releases(v6.38.1)
Owner
Algolia
Open source tools for building search. Learn more at community.algolia.com
Algolia
Library with interfaces and implementations for integrating React applications with Firebase, AWS and possibly other Auth providers

Library with interfaces and implementations for integrating React applications with Firebase, AWS and possibly other Auth providers

Luiz Chagas 4 Jul 1, 2022
React Native Spring ScrollView V2 is a high performance cross-platform native bounces ScrollView for React Native.(iOS & Android)

React Native Spring ScrollView! React Native Spring ScrollView V2 is a high performance cross-platform native bounces ScrollView for React Native.(iOS

石破天惊 308 Nov 14, 2022
React Native component wrapping the native Facebook SDK login button and manager

Give react-native-fbsdk a try! This project is no longer maintained. If you would like to maintain it, please reach out with a pull request. React Nat

Noah Jorgensen 1.2k Oct 10, 2022
A react native interface for integrating Braintree's native Drop-in Payment UI for Android

react-native-braintree-android A react native interface for integrating Braintree's native Drop-in Payment UI for Android using Braintree's v.zero SDK

Suria Labs 24 Jun 8, 2022
🇨🇭 A React renderer for Three.js (web and react-native)

react-three-fiber react-three-fiber is a React renderer for threejs on the web and react-native. npm install three react-three-fiber These demos are r

Poimandres 20.6k Dec 4, 2022
A complete and cross-platform card.io component for React Native (iOS and Android).

⚠️ Both iOS and Android SDKs have been archived As this wrapper depends on them, there is not much I can do to support new OS versions or fix bugs.. I

Yann Pringault 454 Nov 28, 2022
Customizable Google Places autocomplete component for iOS and Android React-Native apps

Google Maps Search Component for React Native Customizable Google Places autocomplete component for iOS and Android React-Native apps Version 2 of thi

Farid Safi 1.8k Dec 7, 2022
React Native around the Agora RTC SDKs for Android and iOS agora

react-native-agora 中文 This SDK takes advantage of React Native and Agora RTC Video SDK on Android && iOS. Community Contributor The community develope

Agora.io Community 565 Nov 29, 2022
A React Native module to interact with Apple Healthkit and Google Fit.

react-native-fitness react-native-fitness is a library that works on both iOS and Android with it you can interact with Apple Healthkit and Google Fit

Oval Money 313 Nov 22, 2022
In-app feedback and bug reporting tool for React Native

Instabug for React Native Instabug is an in-app feedback and bug reporting tool for mobile apps. With just a simple shake, your users or beta testers

Instabug 256 Dec 1, 2022
React Native around the Agora RTM SDKs for Android and iOS agora

agora-react-native-rtm Description The agora-react-native-rtm is an open-source wrapper for react-native developers. This SDK takes advantage of React

Agora.io 55 Nov 29, 2022
react-native interface to share images and videos within instagram

react-native-instagram-share react-native interface to share images and videos within instagram (iOS) Update Instagram does not support the caption fu

null 31 Nov 28, 2020
React Native Conekta SDK for iOS and Android

React Native Conekta React Native Conekta SDK for iOS and Android Supported React Native Versions Component Version RN Versions README 1.0.4 <= 0.16 O

Jorge Trujillo 28 Mar 31, 2022
React Native wrapper for Intercom.io

react-native-intercom React Native wrapper for Intercom.io. Based off of intercom-cordova Installation Guide Install Intercom for iOS via whichever me

Tiny Creative 409 Sep 30, 2022
Facebook Account Kit SDK wrapper for React Native

React Native Facebook Account Kit A Facebook Account Kit SDK wrapper for react-native. IMPORTANT: Deprecation Notice As announced by Facebook the Acco

Underscope 319 Nov 11, 2022
A React-Native Bridge for the Google Dialogflow (API.AI) SDK

react-native-dialogflow (react-native-api-ai) A React-Native Bridge for the Google Dialogflow AI SDK. Support for iOS 10+ and Android! Dialogflow is a

innFactory 194 Nov 8, 2022
Voximplant mobile SDK for React Native (iOS/Android)

Voximplant SDK for React Native Voximplant Mobile SDK module for React Native. It lets developers embed realtime voice and video communication into Re

Voximplant 191 Nov 19, 2022
card.io component for React Native

card.io component for React Native A fully featured implementation of card.io for iOS and Android. Installation iOS Run npm install react-native-card-

Kayla Technologies 173 Oct 13, 2022
React Native : Twitter Signin

Note: this guide is for TwitterKit 3.3 and ReactNative 0.56+. React Native : Twitter Signin This package provides necessary code to get your social si

null 164 Oct 13, 2022