|
| 1 | +## Recipes |
| 2 | + |
| 3 | +### Asynchonous Repo List |
| 4 | + |
| 5 | +When the sentinel comes into view, you can use the callback to load data, create the next items, and attach them. For this case we're loading Github repositories with pagination. We assume that we don't know the total `length` and we'll want to keep fetching until the (unknown) end of the list. The solution here is to provide a computed boolean value to `hasMore`, in order to tell the sentinel to await more. |
| 6 | + |
| 7 | +```jsx |
| 8 | +import React from 'react'; |
| 9 | +import List from '@researchgate/react-intersection-list'; |
| 10 | + |
| 11 | +const PAGE_SIZE = 20; |
| 12 | + |
| 13 | +export default class extends React.Component { |
| 14 | + state = { |
| 15 | + currentPage: 0, |
| 16 | + isLoading: false, |
| 17 | + repos: [], |
| 18 | + }; |
| 19 | + |
| 20 | + feedList = (repos) => { |
| 21 | + this.setState({ |
| 22 | + isLoading: false, |
| 23 | + hasMore: repos.length > 0, |
| 24 | + repos: [...this.state.repos, ...repos], |
| 25 | + }); |
| 26 | + }; |
| 27 | + |
| 28 | + handleLoadMore = () => { |
| 29 | + const currentPage = this.state.currentPage + 1; |
| 30 | + |
| 31 | + this.setState({ |
| 32 | + isLoading: true, |
| 33 | + currentPage, |
| 34 | + }); |
| 35 | + |
| 36 | + const url = 'https://api.github.com/users/researchgate/repos'; |
| 37 | + const qs = `?type=public&per_page=${PAGE_SIZE}&page=${currentPage}`; |
| 38 | + |
| 39 | + fetch(url + qs) |
| 40 | + .then(response => response.json()) |
| 41 | + .then(this.feedList) |
| 42 | + .catch(err => { |
| 43 | + throw err; |
| 44 | + }); |
| 45 | + }; |
| 46 | + |
| 47 | + renderItems = (items, ref) => ( |
| 48 | + <div className="list" ref={ref}> |
| 49 | + {items} |
| 50 | + </div> |
| 51 | + ); |
| 52 | + |
| 53 | + renderItem = (index, key) => { |
| 54 | + const repo = this.state.repos[index]; |
| 55 | + return ( |
| 56 | + <div key={key}> |
| 57 | + <strong>{repo.name}</strong> |
| 58 | + </div> |
| 59 | + ); |
| 60 | + }; |
| 61 | + |
| 62 | + componentDidMount() { |
| 63 | + this.handleLoadMore(); |
| 64 | + } |
| 65 | + |
| 66 | + render() { |
| 67 | + return ( |
| 68 | + <div> |
| 69 | + {this.state.isLoading && <div className="loading">Loading</div>} |
| 70 | + <List |
| 71 | + itemsRenderer={this.renderItems} |
| 72 | + hasMore={this.state.hasMore} |
| 73 | + length={this.state.repos.length} |
| 74 | + onIntersection={this.handleLoadMore} |
| 75 | + pageSize={PAGE_SIZE} |
| 76 | + > |
| 77 | + {this.renderItem} |
| 78 | + </List> |
| 79 | + </div> |
| 80 | + ); |
| 81 | + } |
| 82 | +} |
| 83 | +``` |
| 84 | + |
| 85 | +If it's possible to get the total `length` in advance, we won't need `hasMore` and the `pageSize` will be used to paginate results until we reach the bottom of the list. |
| 86 | + |
| 87 | +### Infinite Synchronous List |
| 88 | + |
| 89 | +```jsx |
| 90 | +import React from 'react'; |
| 91 | +import List from '@researchgate/react-intersection-list'; |
| 92 | + |
| 93 | +export default () => ( |
| 94 | + <List length={Infinity}> |
| 95 | + {(index, key) => <div key={key}>{index}</div>} |
| 96 | + </List> |
| 97 | +); |
| 98 | +``` |
| 99 | + |
| 100 | +### Can I submit a new recipe? |
| 101 | + |
| 102 | +Yes, of course! |
| 103 | + |
| 104 | +1. Fork the code repo. |
| 105 | +2. Create your new recipe in the correct subfolder within `./docs/docs/components/` (create a new folder if it doesn't already exist). |
| 106 | +3. Make sure you have included a README as well as your source file. |
| 107 | +4. Submit a PR. |
| 108 | + |
| 109 | +_If you haven't yet, please read our [contribution guidelines](https://github.com/researchgate/react-intersection-list/blob/master/.github/CONTRIBUTING.md)._ |
| 110 | + |
| 111 | +### What license are the recipes released under? |
| 112 | + |
| 113 | +By default, all newly submitted code is licensed under the MIT license. |
| 114 | + |
| 115 | +### How else can I contribute? |
| 116 | + |
| 117 | +Recipes don't always have to be code - great documentation, tutorials, general tips and even general improvements to our examples folder are greatly appreciated. |
0 commit comments