SHARE
TWEET

Untitled

a guest Oct 10th, 2019 67 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, { useState, useEffect } from 'react'
  2. import {
  3.   SafeAreaView,
  4.   View,
  5.   FlatList,
  6.   StyleSheet,
  7.   Text,
  8.   Dimensions
  9. } from 'react-native'
  10.  
  11. const useInfiniteScroll = load => {
  12.   const [isFetching, setIsFetching] = useState(true)
  13.   const [data, setData] = useState([])
  14.  
  15.   useEffect(() => {
  16.     let didCancel = false
  17.     if (!isFetching) return
  18.  
  19.     const loadAsync = async () => {
  20.       const lastIndex = data.length
  21.       const lastItem = data.length ? data[lastIndex] : null
  22.  
  23.       const newData = await load({ lastIndex, lastItem })
  24.       if (!didCancel) {
  25.         setData(prevState => [...prevState, ...newData])
  26.         setIsFetching(false)
  27.       }
  28.     }
  29.  
  30.     loadAsync()
  31.  
  32.     return () => {
  33.       didCancel = true
  34.     }
  35.   }, [isFetching])
  36.  
  37.   return [data, isFetching, setIsFetching]
  38. }
  39.  
  40. const INITIAL_LOAD = 30
  41. const PAGE_SIZE = 20
  42.  
  43. export default () => {
  44.   /**
  45.    * Right now, I'm mandating that whatever this method is accepts as a
  46.    * parameter an object containing the objects `lastIndex` and `lastObject`
  47.    * respectively. I believe this should suffice for effective paging.
  48.    *
  49.    * @param lastIndex
  50.    * @returns {Promise<R>}
  51.    */
  52.   const fetchMoreListItems = ({ lastIndex }) => {
  53.     // Simulate fetch of next 20 items (30 if initial load)
  54.     return new Promise(resolve => {
  55.       setTimeout(() => {
  56.         resolve([
  57.           ...Array.from(
  58.             Array(lastIndex === 0 ? INITIAL_LOAD : PAGE_SIZE).keys(),
  59.             n => {
  60.               n = n + lastIndex
  61.               return {
  62.                 number: n.toString(),
  63.                 id: n.toString()
  64.               }
  65.             }
  66.           )
  67.         ])
  68.       }, 2000)
  69.     })
  70.   }
  71.  
  72.   const [data, isFetching, setIsFetching] = useInfiniteScroll(
  73.     fetchMoreListItems
  74.   )
  75.  
  76.   return (
  77.     <SafeAreaView style={styles.container}>
  78.       <View style={styles.blueBox}>
  79.         <Text style={styles.bigWhiteBoldText}>
  80.           {`${data.length} Items Loaded`}
  81.         </Text>
  82.       </View>
  83.       <FlatList
  84.         onEndReachedThreshold={7}
  85.         onEndReached={() => {
  86.           if (!isFetching) {
  87.             setIsFetching(true)
  88.           }
  89.         }}
  90.         data={data}
  91.         keyExtractor={item => item.id}
  92.         renderItem={({ item }) => {
  93.           return <Item item={item} />
  94.         }}
  95.       />
  96.       {isFetching && (
  97.         <View style={styles.blueBox}>
  98.           <Text style={styles.bigWhiteBoldText}>(Fetching More)</Text>
  99.         </View>
  100.       )}
  101.     </SafeAreaView>
  102.   )
  103. }
  104.  
  105. class Item extends React.PureComponent {
  106.   render() {
  107.     return (
  108.       <View style={styles.item}>
  109.         <Text style={styles.title}>{this.props.item.number}</Text>
  110.       </View>
  111.     )
  112.   }
  113. }
  114.  
  115. const styles = StyleSheet.create({
  116.   container: {
  117.     flex: 1,
  118.     marginTop: 24,
  119.     backgroundColor: 'yellow'
  120.   },
  121.   item: {
  122.     backgroundColor: '#f9c2ff',
  123.     alignItems: 'center',
  124.     justifyContent: 'center',
  125.     height: Dimensions.get('window').height * 0.45,
  126.     marginVertical: 8,
  127.     marginHorizontal: 16
  128.   },
  129.   title: {
  130.     fontSize: 48
  131.   },
  132.   blueBox: {
  133.     height: 50,
  134.     backgroundColor: 'blue',
  135.     justifyContent: 'center',
  136.     alignItems: 'center'
  137.   },
  138.   bigWhiteBoldText: {
  139.     color: 'white',
  140.     fontSize: 32,
  141.     fontWeight: 'bold'
  142.   }
  143. })
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top