After trying redux-infinite-scroll and react-infinite, I had to adapt them to fit my needs and I ended up starting over.
This module is a lot inspired on the work mention above. Thanks guys !
I decided to publish this in case someone find himself with the same use cases that I struggled with. If it doesn't fit your need, lookup react-infinite and redux-infinite-scroll
npm install --save react-lazy-infinite
You also need a need a generator polyfill like babel-polyfill
.
react
react-dom
react-addons-pure-mixin
A solution for long scrollable lists with SAME-HEIGHT-items
- Lazy load/fetch/prepare the data with
props.fetchMore
when approaching the last item (given with the props totalNumberOfItems) - Automatically calculated height
- For performance purposes, only the visible items and a few buffer items are rendered
- All items must have the same height: This is to allow the height to be automatically calculated. The height of the first item to be rendered is assume to be the same height than all the items.
- PropTypes.object
- Inline style for the container
- PropTypes.string
- Default to
'tbody'
- The container of the items
- PropTypes.bool.isRequired
- Tells when to stop fetching
- PropTypes.number
- Default to 15
- Since the height of the items can only be calculated once rendered, the initial render can not know how many items to render
- Once an item is rendered,
componentHeight / itemHeight
is used
- PropTypes.node.isRequired
- Element or component to render to let the user know it's fetching/loading
- PropTypes.number.isRequired
- Number of items
- PropTypes.func.isRequired
- Function to call to fetch more items for the initial fetch and the lazy-load fetch when approaching the bottom of the list
- PropTypes.func.isRequired
- Fonction to get the items component to render
...
import InfiniteScroll from 'react-lazy-infinite'
class MyList extends React.Component {
static propsType {
fetchIngredients: PropTypes.func.isRequired,
ingredients: PropTypes.array.isRequired,
hasMoreIngredientsToFetch: PropTypes.bool.isRequired
}
render () {
return (
</table>
<InfiniteScroll
fetchMore={this.props.fetchIngredients}
hasMore={this.props.hasMoreIngredientsToFetch}
loader={<tr><td>Keep smiling, we're almost there...</td></tr>}
renderItems={this.renderIngredientEntries}
totalNumberOfItems={this.props.ingredients.length}
/>
</table>
)
}
renderIngredientEntries = (startIndex, endIndex) => {
const ingredientsToDisplay = this.props.ingredients.slice(startIndex, endIndex + 1)
const ingredientsEntries = ingredientsToDisplay.map(
(i) => <IngredientEntry key={i.id} {...i} />
)
return ingredientsEntries
}
}
Always welcome ! I'm sure you can help making this better :)