54
loading...
This website collects cookies to deliver better user experience
const matchDark = '(prefers-color-scheme: dark)'
const useDarkMode = () => {
const [isDark, setIsDark] = useState(() => {
if (process.browser) {
return window.matchMedia && window.matchMedia(matchDark).matches
}
return false
})
return isDark
}
export default useDarkMode
window.matchMedia
and listen for when it changes.const matchDark = '(prefers-color-scheme: dark)'
const useDarkMode = () => {
const [isDark, setIsDark] = useState(() => {
if (process.browser) {
return window.matchMedia && window.matchMedia(matchDark).matches
}
return false
})
useEffect(() => {
const matcher = window.matchMedia(matchDark)
const onChange = ({ matches }: MediaQueryListEvent) => setIsDark(matches)
matcher.addListener(onChange)
return () => {
matcher.removeListener(onChange)
}
}, [setIsDark])
return isDark
}
export default useDarkMode
import useDarkMode from "@hooks/useDarkMode";
const App = () => {
const theme = useDarkMode() ? themes.dark : themes.light;
return (
<ThemeProvider value={theme}>
...
</ThemeProvider>
)
}
const useInView = (
elRef: MutableRefObject<HTMLElement | null>,
onChange?: (_inView: boolean) => void
) => {
const [inView, setInView] = useState(false)
useEffect(() => {
const onScroll = () => {
if (!elRef.current) return
const boundingRect = elRef.current.getBoundingClientRect()
const elementHeight = elRef.current.offsetHeight
const offsetTop = boundingRect.top
const windowHeight = window.innerHeight
const isVisible =
offsetTop + elementHeight > 0 && offsetTop < windowHeight
if (isVisible && !inView) {
setInView(isVisible)
onChange && onChange(isVisible)
} else if (!isVisible && inView) {
setInView(isVisible)
onChange && onChange(isVisible)
}
}
window.addEventListener('scroll', onScroll)
return () => {
window.removeEventListener('scroll', onScroll)
}
}, [elRef, onChange, inView])
return inView
}
import React, { useRef } from 'react'
import useInView from '@hooks/useInView'
const Hooks = () => {
const elementRef = useRef<HTMLDivElement>(null)
// use as a variable
const inView = useInView(elementRef)
// or use a callback
useInView(elementRef, (isInView) => {
console.log(isInView ? 'element has appeared' : 'element has disappeared');
})
return (
<div className="w-full max-w-screen-md">
<div className="h-screen"></div>
<div
ref={elementRef}
className={`py-6 text-center ${
inView ? 'bg-blue-100' : 'bg-red-100'
}`}>
Is in view: {inView ? 'true' : 'false'}
</div>
<div className="h-screen"></div>
</div>
)
}
export default Hooks