Created
June 13, 2019 16:14
-
-
Save JoostKiens/9f7712cfa673c1442a7d47c94fe66579 to your computer and use it in GitHub Desktop.
React useScroll hook (window scrolling) returns scrollX & scrollY, with context provider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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