Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rootMargin doesn't work when root default to null #32

Open
iamyoki opened this issue Feb 17, 2022 · 2 comments
Open

rootMargin doesn't work when root default to null #32

iamyoki opened this issue Feb 17, 2022 · 2 comments

Comments

@iamyoki
Copy link

iamyoki commented Feb 17, 2022

See this example in codesandbox

https://codesandbox.io/s/try-react-infinite-scroll-hook-4ekfj1?file=/src/App.jsx:1374-1384

This is a common pitfall when using rootMargin without root specified

Little rules of Interception Observer API
root default to viewport while the viewport doesn't have any margin, so set rootMargin to any value will always fallback to 0px .

@iamyoki
Copy link
Author

iamyoki commented Feb 17, 2022

I may implemented a better version of this hook

Easier to use, less properties required, same ability, here is a simple usage:

export default function App() {
  const [list, setList] = useState([...Array(11).keys()])
  const { containerRef, isLoading } = useInfiniteScroll({
    async onLoadMore() {
      const res = await fetchList(list.slice(-1)[0])
      setList(list.concat(res))
    },
  })

  return (
    <div className="App">
      <List ref={containerRef}>
        {list.map((n) => (
          <Item key={n}>{n}</Item>
        ))}
        {isLoading && <Loading>Loading ...</Loading>}
      </List>
    </div>
  )

Use offset against rootMargin

Will load more while to bottom offset '200px'

const { containerRef, isLoading } = useInfiniteScroll({offset: '200px'})
...

All css size units available

  • offset: 200px
  • offset: 20%
  • offset: 20vh
  • offset: 20cm
  • ...

Extra bonus

Using offset: 200px as absolute distance to bottom offset.
Using offset: 20% as relative distance to bottom offset, it will insure the trigger point always stick to the 80% height of scrollbar.

Stop while finished

const { containerRef, isLoading } = useInfiniteScroll({shouldStop: isFetchEnd})
...

return (
    <div className="App">
      <List ref={containerRef}>
        {list.map((n) => (
          <Item key={n}>{n}</Item>
        ))}
        {(isLoading || !isFetchEnd) && <Loading>Loading ...</Loading>}
      </List>
    </div>
  )

Talk is cheap, check out the source code :)

https://codesandbox.io/s/better-react-infinite-scroll-hook-kgup0w?file=/src/useInfiniteScroll.js

@iamyoki
Copy link
Author

iamyoki commented Feb 18, 2022

Update the next day:

I made it to become another independent library https://github.com/iamyoki/infinite-scroll-hook

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant