Advertisement
Guest User

Untitled

a guest
Oct 10th, 2019
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.15 KB | None | 0 0
  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. })
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement