Giter Site home page Giter Site logo

Comments (8)

alexpchin avatar alexpchin commented on May 2, 2024

#37

from react-native-collapsible-tab-view.

PedroBern avatar PedroBern commented on May 2, 2024

Hi @alexpchin we can't do it. The solution is to display the algolia search results in the flatlist, instead of in the ListHeaderComponent.

I have a case like this, where I have a HoC component (createPaginationContainer) for each tab of my collapsible tabs.

from react-native-collapsible-tab-view.

alexpchin avatar alexpchin commented on May 2, 2024

@PedroBern I've actually just realised that root was removed from InstantSearch in algolia/react-instantsearch#2339 So (using the basic code structure below as one of my tabs), InstantSearch does not actually wrap Hits in another component.

I updated the PR to show an example with Algolia.

If you have any time to have a read, it would be extremly helpful. Currently, it is like this:

import * as React from 'react';
import {
  Text,
  Animated,
  View,
  StyleSheet,
  Image,
  Dimensions,
} from 'react-native';
import { useCollapsibleScene } from 'react-native-collapsible-tab-view';
import useRefresh from './useRefresh';
import { useAnimatedValueContext } from './AnimatedContext';

import {
  InstantSearch,
  Configure,
  connectInfiniteHits,
} from 'react-instantsearch-native';
import algoliasearch from 'algoliasearch/lite';

const { width } = Dimensions.get('window');

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

const ListEmptyComponent = ({ routeKey }: any) => {
  const animatedValue = useAnimatedValueContext();
  const {
    contentContainerStyle: { paddingTop },
  } = useCollapsibleScene(routeKey);

  const [translateY] = React.useState(
    animatedValue.interpolate({
      inputRange: [0, paddingTop - 49], // 49 is the default tabBar height, use your value here
      outputRange: [-(paddingTop - 49) / 2, 0],
      extrapolateRight: 'clamp',
    })
  );

  return (
    <Animated.View
      style={{
        alignItems: 'center',
        flex: 1,
        justifyContent: 'center',
        transform: [{ translateY }],
        borderColor: 'black',
        borderWidth: 10,
      }}
    >
      <Text>Centered Empty List!</Text>
    </Animated.View>
  );
};

const ItemSeparator = () => <View style={styles.separator} />;

const ConnectedHits = connectInfiniteHits(
  ({ hits, hasMore, refine, routeKey }: any) => {
    const [isRefreshing, startRefreshing] = useRefresh();

    const scenePropsAndRef = useCollapsibleScene(routeKey);

    const onEndReached = () => {
      if (hasMore) {
        refine();
      }
    };

    const renderItem = ({ item }: any) => (
      <View style={styles.item}>
        <Image
          style={{ height: width, width: width }}
          source={{ uri: item.image }}
        />
      </View>
    );

    return (
      <Animated.FlatList
        data={hits}
        onEndReached={onEndReached}
        keyExtractor={(_, i) => String(i)}
        renderItem={renderItem}
        ItemSeparatorComponent={ItemSeparator}
        refreshing={isRefreshing}
        onRefresh={startRefreshing}
        ListEmptyComponent={() => <ListEmptyComponent routeKey={routeKey} />}
        {...scenePropsAndRef}
      />
    );
  }
);

export const Algolia = ({ hitsPerPage = 10, routeKey = 'algolia' }) => (
  <InstantSearch indexName="instant_search" searchClient={searchClient}>
    <Configure hitsPerPage={hitsPerPage} />
    {/* @ts-ignore */}
    <ConnectedHits routeKey={routeKey} />
  </InstantSearch>
);

const styles = StyleSheet.create({
  item: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: 'white',
  },
  separator: {
    height: 1,
    backgroundColor: 'white',
  },
});

With the example rendering two Algolia lists, one with data and one without.

import * as React from 'react';
import { StyleSheet, View, Text, Animated } from 'react-native';
import { SceneMap } from 'react-native-tab-view';

import { CollapsibleTabView } from 'react-native-collapsible-tab-view';

import { AnimatedValueContextProvider } from './Shared/AnimatedContext';

import { Algolia } from './Shared/Algolia';
import { ExampleComponentType } from './types';

type Route = {
  key: string;
  title: string;
};

export const AlgoliaScene = () => <Algolia routeKey="algolia" />;

export const AlgoliaEmptyScene = () => (
  <Algolia hitsPerPage={0} routeKey="algoliaEmpty" />
);

export const HEADER_HEIGHT = 250;

const renderHeader = () => (
  <View style={styles.header}>
    <Text style={styles.headerText}>COLLAPSIBLE</Text>
  </View>
);

const renderScene = SceneMap({
  algolia: AlgoliaScene,
  algoliaEmpty: AlgoliaEmptyScene,
});

const CollapsibleTabViewExample: ExampleComponentType = () => {
  const [index, setIndex] = React.useState(0);
  const [routes] = React.useState<Route[]>([
    { key: 'algolia', title: 'Algolia' },
    { key: 'algoliaEmpty', title: 'Algolia Empty' },
  ]);

  const handleIndexChange = (index: number) => {
    setIndex(index);
  };

  const [animatedValue] = React.useState(new Animated.Value(0));

  return (
    <AnimatedValueContextProvider value={animatedValue}>
      <CollapsibleTabView<Route>
        animatedValue={animatedValue}
        navigationState={{ index, routes }}
        renderScene={renderScene}
        onIndexChange={handleIndexChange}
        renderHeader={renderHeader}
        headerHeight={HEADER_HEIGHT}
      />
    </AnimatedValueContextProvider>
  );
};

CollapsibleTabViewExample.title = 'Algolia example';
CollapsibleTabViewExample.backgroundColor = '#2196f3';
CollapsibleTabViewExample.appbarElevation = 0;

export default CollapsibleTabViewExample;

const styles = StyleSheet.create({
  header: {
    height: HEADER_HEIGHT,
    backgroundColor: '#2196f3',
    justifyContent: 'center',
    alignItems: 'center',
    elevation: 4,
  },
  headerText: {
    color: 'white',
    fontSize: 24,
  },
});

from react-native-collapsible-tab-view.

PedroBern avatar PedroBern commented on May 2, 2024

@alexpchin I fetched and ran the example, what's the bug? Everything is working. The images are loaded and when I switch tabs the centered list empty is in the correct position

from react-native-collapsible-tab-view.

alexpchin avatar alexpchin commented on May 2, 2024

@PedroBern Typical. I've re-run the example and it also seems to be working for me. I'll double-check things...

from react-native-collapsible-tab-view.

PedroBern avatar PedroBern commented on May 2, 2024

@alexpchin typical 😄 is everything work?

from react-native-collapsible-tab-view.

alexpchin avatar alexpchin commented on May 2, 2024

@PedroBern Wow this has been very frustrating!

In my project, I moved useCollapsibleScene to the parent component and then passed through the scenePropsAndRef through to the ConnectedHits so that ConnectedHits could be reused in places other than within a react-native-collapsible-tab-view.

E.g.

export const Algolia = ({ hitsPerPage, routeKey = 'algolia' }: any) => {
  const scenePropsAndRef = useCollapsibleScene(routeKey);
  return (
    <InstantSearch indexName="instant_search" searchClient={searchClient}>
      <Configure hitsPerPage={hitsPerPage} />
      <ConnectedHits
        // @ts-ignore
        routeKey={routeKey}
        {...scenePropsAndRef}
      />
    </InstantSearch>
  );
};

However, due to the ref not being forwarded correctly, with the HOC connectInfiniteHits being annoying, I then changed to:

export const Algolia = ({ hitsPerPage, routeKey = 'algolia' }: any) => {
  const { ref, ...scenePropsWithoutRef } = useCollapsibleScene(routeKey);
  return (
    <InstantSearch indexName="instant_search" searchClient={searchClient}>
      <Configure hitsPerPage={hitsPerPage} />
      <ConnectedHits
        // @ts-ignore
        routeKey={routeKey}
        forwardRef={ref}
        {...scenePropsWithoutRef}
      />
    </InstantSearch>
  );
};

This way, I then pass the ref down multiple components as the renamed prop forwardRef and then attach it as ref to the Animated.Flatlist.

This version is now working too.

from react-native-collapsible-tab-view.

alexpchin avatar alexpchin commented on May 2, 2024

Closing as this is resolved now.

from react-native-collapsible-tab-view.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.