Loading prop alternating in react native with nested connectors

Hi, I’m trying to get a loading screen working with the connectInfiniteHits connector. I initially added the loading (searchResults.searching) props directly into connectInfiniteHits which worked ok, but it’s problematic for my cloud build/would be overwritten whenever I updated Algolia dependencies.

But if I do it with nested connectors, I get a weird infinite loop where the loading prop alternates between true and false. I’m pretty sure I’m not changing state or starting a search in any of the child components, so not sure what’s going on here?

I have a structure that looks like:

Top-most connector:

const connectResults = createConnector({
  displayName: 'ConditionalErrorLoading',
  getProvidedProps(props, searchState, searchResults) {
    return {
      error: searchResults.error,
      loading: searchResults.searching
    };
  },
});

which wraps around my <Results /> component:

export default class Results extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    var { error, homeState, loading } = this.props;
    // console.log("Results props", this.props);
    console.log("results loading", loading);
    // console.log("error", error);
    return (
      <View style={{flex: 1}}>
        <ConnectedHits error={error} homeState={homeState} loading={loading} />
      </View>
    )
  }
}

which renders my ConnectedHits = connectInfiniteHits(Hits) component.

<Hits /> then renders my displayed FlatList components/loading spinner/error messages.

If I manually set the loading prop to false for ConnectedHits, the alternating behaviour doesn’t happen. Is there some potential conflict with nesting connectors like this?

That sounds indeed like there’s a conflict happening somewhere, could you try making a reproducible example in something like codesandbox.io or jsfiddle. If you know about a similar service like snack that works with external dependencies, that would be even better

Hi, I looked around but unfortunately couldn’t find an online compiler that supports external dependencies. I wrote an example index.android.js file that reproduces the issue.

import React, { Component } from 'react';
import { AppRegistry, Text, View, StyleSheet } from 'react-native';
import { InstantSearch } from 'react-instantsearch/native';
import { createConnector } from 'react-instantsearch';
import { connectInfiniteHits } from 'react-instantsearch/connectors';

class App extends Component {
  render() {
    return (
      <View style={styles.container}>
        <InstantSearch
          appId="98JPJ8HORA"
          apiKey="80acd9fd0890a7603560db24b042f6a6"
          indexName="QXBwOjY5OGVlMGNjLWU4MmMtNDcwMi04MWE0LWU5MjQ0MTMwMGQ4Yw==.Product"
        >
          <ConnectedResults />
        </InstantSearch>
      </View>
    );
  }
}

const connectResults = createConnector({
  displayName: 'ConditionalErrorLoading',
  getProvidedProps(props, searchState, searchResults) {
    return {
      error: searchResults.error,
      loading: searchResults.searching
    };
  },
});


class Results extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    var { error, loading } = this.props;
    // console.log("Results props", this.props);
    console.log("results loading", loading);
    // console.log("error", error);
    return (
      <View style={{flex: 1}}>
        <ConnectedHits loading={loading} />
      </View>
    )
  }
}

const ConnectedResults = connectResults(Results);

class Hits extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    var {loading} = this.props;
    console.log(loading);
    return (
      <View>
        <Text>{String(loading)}</Text>
      </View>
    )
  }
}
const ConnectedHits = connectInfiniteHits(Hits);


AppRegistry.registerComponent('App', () => App);
1 Like