{"id":13927049,"url":"https://github.com/simbathesailor/react-infinite-scroll","last_synced_at":"2025-04-17T12:42:14.470Z","repository":{"id":35994296,"uuid":"217012710","full_name":"simbathesailor/react-infinite-scroll","owner":"simbathesailor","description":"A  dead simple infinite scroll  (1.3 kb gzipped)  for friends ","archived":false,"fork":false,"pushed_at":"2023-01-05T00:44:20.000Z","size":8114,"stargazers_count":14,"open_issues_count":30,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-24T14:45:48.016Z","etag":null,"topics":["custom-hooks","infinite-scroll","intersection-observer","react-hooks"],"latest_commit_sha":null,"homepage":"https://simbathesailor-react-infinite-scroll.now.sh/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simbathesailor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-23T08:56:52.000Z","updated_at":"2023-03-25T05:04:02.000Z","dependencies_parsed_at":"2023-01-16T11:31:25.474Z","dependency_job_id":null,"html_url":"https://github.com/simbathesailor/react-infinite-scroll","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simbathesailor%2Freact-infinite-scroll","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simbathesailor%2Freact-infinite-scroll/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simbathesailor%2Freact-infinite-scroll/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simbathesailor%2Freact-infinite-scroll/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simbathesailor","download_url":"https://codeload.github.com/simbathesailor/react-infinite-scroll/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249342135,"owners_count":21254228,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["custom-hooks","infinite-scroll","intersection-observer","react-hooks"],"created_at":"2024-08-07T16:01:20.812Z","updated_at":"2025-04-17T12:42:14.448Z","avatar_url":"https://github.com/simbathesailor.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# react-infinite-scroll 📜\n\n### A dead simple React infinite-scroll\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://badgen.net/npm/v/@simbathesailor/react-infinite-scroll\"\u003e\n    \u003cimg src=\"https://badgen.net/bundlephobia/minzip/@simbathesailor/react-infinite-scroll\"\u003e\n    \u003cimg src=\"https://badgen.net/npm/dw/@simbathesailor/react-infinite-scroll\"\u003e\n  \u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"demo-images/demo.gif\" width=\"300\" align=\"center\"\u003e\u003c/p\u003e\n\n#### ✅ Built on new flashy Reactjs hooks.\n\n#### ✅ No assumption on the how you bring data, just wrap the content inside the InfiniteScroll component\n\n#### ✅ Uses Intersection Observer API, hence performant than regular ways of doing it\n\n#### ✅ Completely configurable. Can be used to trigger infinite scroll in any direction.\n\n#### ✅ Takes care of screen resizing\n\n#### ✅ Tiny (1.3kb gzipped)\n\n### Installing\n\nIf using npm:\n\n```sh\n\nnpm i @simbathesailor/react-infinite-scroll --save\n\n```\n\nIf using yarn:\n\n```sh\n\nyarn add @simbathesailor/react-infinite-scroll\n\n```\n\n## Demo\n\n[Demo App](https://nm7ls.csb.app/)\n\n[Full Codesandbox Code](https://codesandbox.io/s/useintersectionobserver-nm7ls)\n\n## Usage\n\n### Scenario: When need to fetch new set of data when scroll end is reached\n\n```jsx\nimport { InfiniteScroll } from '@simbathesailor/react-infinite-scroll';\n\nfunction App() {\n  // setting up the active page fetched, It can be any logic needed\n\n  const [activePageInfo, setActivePageInfo] = React.useState(1);\n\n  // This is data recieved till now, which will be rendered.\n\n  const [dataInfiniteScroll, setDataInfiniteScroll] = React.useState(null);\n\n  // Logic to execute to get the initial set of results\n\n  // On mount of the component , we are making an API call to get\n\n  // the initial set of results.\n\n  React.useEffect(() =\u003e {\n    fetch(\n      `https://5da9aa08de10b40014f3745c.mockapi.io/api/v1/feed?page=1\u0026limit=10`\n    )\n      .then(res =\u003e {\n        return res.json();\n      })\n\n      .then(data =\u003e {\n        setDataInfiniteScroll(data);\n      });\n  }, []);\n\n  // Logic to execute when the reached the end of the scroll\n\n  // This is a callback which can be passed to InfiniteScroll component, The callback\n\n  // will recieve the isVisible value as true when we reach the end of the scroll.\n\n  const callbackForInfiniteScroll = React.useCallback(\n    isVisible =\u003e {\n      let activePage;\n\n      setActivePageInfo(c =\u003e {\n        activePage = c;\n\n        return c;\n      });\n\n      if (isVisible) {\n        fetch(\n          `https://5da9aa08de10b40014f3745c.mockapi.io/api/v1/feed?page=${activePage +\n            1}\u0026limit=10`\n        )\n          .then(res =\u003e {\n            return res.json();\n          })\n\n          .then(data =\u003e {\n            setDataInfiniteScroll(dataInState =\u003e [...dataInState, ...data]);\n\n            setActivePageInfo(c =\u003e c + 1);\n          });\n      }\n    },\n\n    [setActivePageInfo]\n  );\n\n  return (\n    \u003cdiv className=\"App\"\u003e\n      {/* Just need to pass the callback to invoke, when list reaches end */}\n\n      \u003cInfiniteScroll callback={callbackForInfiniteScroll}\u003e\n        {dataInfiniteScroll \u0026\u0026\n          dataInfiniteScroll.map(elem =\u003e {\n            /** Box is not a React element. It's a React component **/\n\n            return \u003cBox key={elem.id} {...elem} /\u003e;\n          })}\n      \u003c/InfiniteScroll\u003e\n    \u003c/div\u003e\n  );\n}\n\n// It is important to use forwardRef when Components are not React Elements.\n\n// InfiniteScroll component takes the responsibility of initiliazing\n\n// the intersection observer for you. ref should resolve to a DOM element\n\nconst Box = React.forwardRef((props, ref) =\u003e {\n  const { avatar, id, name } = props;\n\n  return (\n    \u003cdiv ref={ref} className=\"box-item\"\u003e\n      \u003cimg\n        style={{ height: '60%', width: '60%', marginBottom: '10px' }}\n        src={avatar}\n        alt=\"no-avatar\"\n      /\u003e\n\n      \u003cspan\u003e{name}\u003c/span\u003e\n    \u003c/div\u003e\n  );\n});\n```\n\n### Scenario: When need to fetch new set of data with some offset at bottom of the page.\n\nLet' see only the changed code from above. Infinite scroll takes rootMargin as one of the option similar to intersection observer API. Hence any offset can be given as:\n\nrootMargin: \"[topOffset], [rightOffset], [bottomOffset], [leftOffset]\". Let's see the one of the example having a bottom offset of 680px.\n\n```jsx\n\u003cdiv className=\"App\"\u003e\n  \u003ch1\u003eScroll to see Infinite scroll in action\u003c/h1\u003e\n\n  {/* Just need to pass the callback to invoke, when list reaches end */}\n\n  \u003cInfiniteScroll\n    callback={callbackForInfiniteScroll}\n    options={{\n      rootMargin: `0px 0px 680px 0px`,\n    }}\n  \u003e\n    {dataInfiniteScroll \u0026\u0026\n      dataInfiniteScroll.map(elem =\u003e {\n        return \u003cBox key={elem.id} {...elem} /\u003e;\n      })}\n  \u003c/InfiniteScroll\u003e\n\u003c/div\u003e\n```\n\nWe can also give , top offset, left offset and right offset. So Infinite scroll can be done in any direction. This also support infinite scrolls in scrollable areas apart from viewport. \\*Need to test more on that.\n\n## Props\n\n| Props              | IsMandatory | Type                                                                    | Default                                                                                                     | Description                                                                                                                                                                                |\n| ------------------ | ----------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| callback           | Yes         | (isVisibile) =\u003e {\u003cbr\u003e // Logic to trigger \u003cbr\u003e // next set of data\u003cbr\u003e} |                                                                                                             | A callback from consumer,\u003cbr\u003ewhich gets isVisible boolean\u003cbr\u003eas the argument.                                                                                                              |\n| options            | No          | object                                                                  | {\u003cbr\u003erootMargin: '0px 0px 0px 0px'\u003cbr\u003ethreshold: '0, 1'\u003cbr\u003ewhen: true\u003cbr\u003evisibilityCondition: Function\u003cbr\u003e} | These are the almost same options,\u003cbr\u003ewhich we pass to intersectionObserver\u003cbr\u003eexcept threshold which is changed to string type.\u003cbr\u003eDone for avoiding extra check for array\u003cbr\u003ecomparison. |\n| whenInfiniteScroll | No          | boolean                                                                 | true                                                                                                        | The flag which can be used to stop\u003cbr\u003einfinitescroll behaviour, when false.\u003cbr\u003ecan be used to off when , data is no\u003cbr\u003emore to be fetched.                                                 |\n| LoadMoreComponent  | No          | React.ReactElement                                                      | Loading More...                                                                                             | This is a ReactElement or React Component\u003cbr\u003ewhich is shown when scroll reaches end                                                                                                        |\n\n## Concept\n\nreact-infinite-scroll is using **Intersection Observer API**. Hence very performant and slick. We can pass almost same options we pass for setting up intersection observer. Here is the link for [MDN Intersection observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#root-intersection-rectangle). You can read about it and understand why it is performant.\n\nThe InfiniteScroll Component make use of useInfiniteScroll and useIntersectionObserver hook. React version above \u003e16.8.6 can use this component for infinite scrolling.\n\nPlan is to bundle useIntersectionObserver as a separate package later.\n\n## Work to do\n\n- TestCases.\n\n- Other examples\n\n- Update readme with all the props InfiniteScroll component takes as a table.\n\n- Example how to stop the infinite scroll and sending the custom components as Loader.\n\n## Contributing\n\nPlease read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.\n\n## Versioning\n\nWe use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/your/project/tags).\n\n## Authors\n\n[simbathesailor](https://github.com/simbathesailor)\n\nSee also the list of [contributors](https://github.com/your/project/contributors) who participated in this project.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details\n\n## Contributors\n\nThanks goes to these wonderful people ([emoji key](https://github.com/all-contributors/all-contributors#emoji-key)):\n\n\u003ctable\u003e\u003ctr\u003e\u003ctd  align=\"center\"\u003e\u003ca  href=\"https://github.com/simbathesailor\"\u003e\u003cimg  src=\"https://avatars2.githubusercontent.com/u/5938110?s=400\u0026u=f94d3ad624faa17c799d7bbd88cf2d2170b26813\u0026v=4\"  width=\"100px;\"  alt=\"Anil kumar chaudhary\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAnil kumar Chaudhary\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca  href=\"https://github.com/simbathesailor/react-infinite-scroll/commits?author=simbathesailor\"  title=\"Code\"\u003e💻\u003c/a\u003e  \u003ca  href=\"#ideas-simbathesailor\"  title=\"Ideas, Planning, \u0026 Feedback\"\u003e🤔\u003c/a\u003e  \u003ca  href=\"#design-simbathesailor\"  title=\"Design\"\u003e🎨\u003c/a\u003e  \u003ca  href=\"https://github.com/simbathesailor/react-infinite-scroll/commits?author=simbathesailor\"  title=\"Documentation\"\u003e📖\u003c/a\u003e  \u003ca  href=\"https://github.com/simbathesailor/react-infinite-scroll/issues/created_by/simbathesailor\"  title=\"Bug reports\"\u003e🐛\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimbathesailor%2Freact-infinite-scroll","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimbathesailor%2Freact-infinite-scroll","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimbathesailor%2Freact-infinite-scroll/lists"}