Ask questionsKeep getting `TypeError: Cannot read property 'scrollTop' of null` in a custom hook...
I made a hook to get the scroll position of a component, like so:
function useScrollPosition() {
function getScroll() {
return {
x: document.getElementById('ContentContainer').scrollTop,
y: document.getElementById('ContentContainer').scrollLeft
}
}
const [scrollPosition, setScrollPosition] = useState(getScroll)
useEffect(() => {
function handleScroll() {
setScrollPosition(getScroll())
}
window.addEventListener('scroll', handleScroll)
return () => window.removeEventListener('scroll', handleScroll)
}, []) // Empty array ensures that effect is only run on mount and unmount
return scrollPosition
}
...and implemented it in the same file, like so:
const ContentContainer = (props) => {
const scroll = useScrollPosition();
return (
<Main id='ContentContainer'>
<ScrollInfo>
Vertical position: {scroll.x}px / Horizontal Position: {scroll.y}px
</ScrollInfo>
{props.children}
</Main>
)
}
export default ContentContainer
...and i keep getting the same error:
If I disable the hook and the app runs properly, I can then find the scroll position in the console just fine.
Any thoughts as to why I might be getting null
back for something that clearly isn't null
when the app loads without this hook enabled?
Answer
questions
rchrdnsh
ok, I've tried to update the code using useRef
, like so:
import React, { useState, useEffect, useRef } from 'react'
import styled from 'styled-components'
// styled components
const Main = styled.main`
...stylezzzz...
`
const ScrollInfo = styled.div`
...stylezzzz...
`
// hook
function useScrollPosition() {
const elementRef = useRef(null);
function getScroll() {
const data = elementRef.current ?
elementRef.current.getBoundingCLientRect() : 0;
const { bottom, top, left, right } = data;
return { bottom, top, left, right };
}
const [scrollPosition, setScrollPosition] = useState(getScroll)
useEffect(() => {
function handleScroll() {
setScrollPosition(getScroll())
}
window.addEventListener('scroll', handleScroll)
return () => window.removeEventListener('scroll', handleScroll)
}, []) // Empty array ensures that effect is only run on mount and unmount
return scrollPosition
}
// component
const ContentContainer = (props) => {
const scroll = useScrollPosition();
return (
<Main ref={elementRef} id='ContentContainer'>
<ScrollInfo>
From Top: {scroll.top}px <br/>
From Bottom: {scroll.bottom}px <br/>
From Left: {scroll.left}px <br/>
From right: {scroll.right}px <br/>
Vertical Scroll: {scroll.y}px <br/>
Horizontal Scroll: {scroll.x}px
</ScrollInfo>
{props.children}
</Main>
)
}
export default ContentContainer
and I'm currently getting the following error:
122:16 error 'elementRef' is not defined no-undef
✖ 1 problem (1 error, 0 warnings)
@ ./src/components/Layout.js 17:0-45 91:140-144
@ ./node_modules/gatsby-plugin-layout/wrap-page.js
@ ./node_modules/gatsby-plugin-layout/gatsby-browser.js
@ ./.cache/api-runner-browser-plugins.js
@ ./.cache/api-runner-browser.js
@ ./.cache/app.js
@ multi ./node_modules/event-source-polyfill/src/eventsource.js
ℹ 「wdm」: Failed to compile.
but it appears that I am defining the ref at the beginning of the hook, no? Not sure how to adjust it to work properly.
Related questions