Skip to content

Instantly share code, notes, and snippets.

@JoostKiens
Created June 13, 2019 16:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoostKiens/9f7712cfa673c1442a7d47c94fe66579 to your computer and use it in GitHub Desktop.
Save JoostKiens/9f7712cfa673c1442a7d47c94fe66579 to your computer and use it in GitHub Desktop.
React useScroll hook (window scrolling) returns scrollX & scrollY, with context provider
import React from 'react'
const ScrollContext = React.createContext(null)
export function useScroll() {
const scroll = React.useContext(ScrollContext)
if (!scroll)
throw new Error('Please make sure ScrollContextProvider is available')
return scroll
}
export function ScrollContextProvider({ children }) {
const scroll = useRawScroll()
return (
<ScrollContext.Provider value={scroll}>{children}</ScrollContext.Provider>
)
}
export const useRawScroll = () => {
const [scrollX, setScrollX] = React.useState(0)
const [scrollY, setScrollY] = React.useState(0)
// Performance optimization, see: http://www.html5rocks.com/en/tutorials/speed/animations/
let lastKnownScrollX = scrollX
let lastKnownScrollY = scrollY
let ticking = false
React.useEffect(() => {
if (window) window.addEventListener('scroll', handleScroll)
return () => {
if (window) window.removeEventListener('scroll', handleScroll)
}
})
function handleScroll() {
lastKnownScrollX = window.scrollX
lastKnownScrollY = window.scrollY
if (!ticking) {
window.requestAnimationFrame(() => {
setScrollX(lastKnownScrollX)
setScrollY(lastKnownScrollY)
ticking = false
})
ticking = true
}
}
return { scrollX, scrollY }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment